diff --git a/.changeset/README.md b/.changeset/README.md deleted file mode 100644 index e5b6d8d6a..000000000 --- a/.changeset/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changesets - -Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works -with multi-package repos, or single-package repos to help you version and publish your code. You can -find the full documentation for it [in our repository](https://github.com/changesets/changesets) - -We have a quick list of common questions to get you started engaging with this project in -[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json index e0ff10a85..958d98e14 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,12 +1,18 @@ { - "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", - "changelog": [ - "@changesets/cli/changelog", - { "repo": "ArkProjectNFTs/ark-project" } - ], + "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", + "changelog": "@changesets/cli/changelog", "commit": false, - "access": "public", + "fixed": [], + "linked": [], + "access": "restricted", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": [] -} + "ignore": [ + "@ark-project/core-examples" + ], + "packages": [ + "@ark-project/react", + "@ark-project/core", + "@ark-project/eslint-config" + ] +} \ No newline at end of file diff --git a/.changeset/empty-files-trade.md b/.changeset/empty-files-trade.md new file mode 100644 index 000000000..0fea963f4 --- /dev/null +++ b/.changeset/empty-files-trade.md @@ -0,0 +1,7 @@ +--- +"@ark-project/react": patch +"@ark-project/core": patch +"@ark-project/test": patch +--- + +chore: bump starknet-react to version 3 diff --git a/.changeset/flat-chefs-repair.md b/.changeset/flat-chefs-repair.md new file mode 100644 index 000000000..13dfad1dc --- /dev/null +++ b/.changeset/flat-chefs-repair.md @@ -0,0 +1,6 @@ +--- +"@ark-project/react": major +"@ark-project/core": major +--- + +Update SDKs diff --git a/.changeset/hungry-bobcats-push.md b/.changeset/hungry-bobcats-push.md new file mode 100644 index 000000000..7cfa59711 --- /dev/null +++ b/.changeset/hungry-bobcats-push.md @@ -0,0 +1,6 @@ +--- +"@ark-project/react": patch +"@ark-project/core": patch +--- + +Update contract address diff --git a/.changeset/moody-gorillas-mate.md b/.changeset/moody-gorillas-mate.md new file mode 100644 index 000000000..22c552b5a --- /dev/null +++ b/.changeset/moody-gorillas-mate.md @@ -0,0 +1,6 @@ +--- +"@ark-project/react": minor +"@ark-project/core": minor +--- + +Update contract diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000..34200964f --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,20 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "@ark-project/core-examples": "0.0.6", + "@ark-project/core": "3.0.0-beta.1", + "@ark-project/deployer": "1.0.1", + "@ark-project/eslint-config": "0.0.0", + "@ark-project/react": "2.0.0-beta.0", + "@ark-project/test": "1.0.0", + "@ark-project/typescript-config": "0.0.0" + }, + "changesets": [ + "flat-chefs-repair", + "hungry-bobcats-push", + "moody-gorillas-mate", + "small-crabs-confess", + "wild-panthers-confess" + ] +} diff --git a/.changeset/small-crabs-confess.md b/.changeset/small-crabs-confess.md new file mode 100644 index 000000000..e24ffbd2d --- /dev/null +++ b/.changeset/small-crabs-confess.md @@ -0,0 +1,5 @@ +--- +"@ark-project/react": minor +--- + +Update for provider diff --git a/.changeset/spicy-roses-shake.md b/.changeset/spicy-roses-shake.md new file mode 100644 index 000000000..c84c01b4c --- /dev/null +++ b/.changeset/spicy-roses-shake.md @@ -0,0 +1,6 @@ +--- +"@ark-project/react": patch +"@ark-project/core": patch +--- + +chore: bump starknet-react & starknet diff --git a/.changeset/wild-panthers-confess.md b/.changeset/wild-panthers-confess.md new file mode 100644 index 000000000..5820ba14d --- /dev/null +++ b/.changeset/wild-panthers-confess.md @@ -0,0 +1,5 @@ +--- +"@ark-project/react": patch +--- + +Export query provider diff --git a/.env.example b/.env.example index 60cffdbea..50969f171 100644 --- a/.env.example +++ b/.env.example @@ -1,60 +1,31 @@ -# DEV -# Starknet accounts dev -# Responsible for deploying the contracts on starknet -STARKNET_ADMIN_ADDRESS_DEV=0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca -STARKNET_ADMIN_PRIVATE_KEY_DEV=0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a -# Responsible for doing the transactions on starknet from the sequencer -STARKNET_SOLIS_ACCOUNT_ADDRESS_DEV=0x2d71e9c974539bb3ffb4b115e66a23d0f62a641ea66c4016e903454c8753bbc -STARKNET_SOLIS_ACCOUNT_PRIVATE_KEY_DEV=0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b -# Solis accounts dev -# Responsible for deploying the contracts on solis dev -SOLIS_ADMIN_ADDRESS_DEV=0x6b86e40118f29ebe393a75469b4d926c7a44c2e2681b6d319520b7c1156d114 -SOLIS_ADMIN_PRIVATE_KEY_DEV=0x1c9053c053edf324aec366a34c6901b1095b07af69495bffec7d7fe21effb1b +# Accounts +STARKNET_ADMIN_ADDRESS_DEV= +STARKNET_ADMIN_PRIVATE_KEY_DEV= +STARKNET_ADMIN_PUBLIC_KEY_DEV= -# SEPOLIA -# Starknet account sepolia -# Responsible for deploying the contracts on starknet -STARKNET_ADMIN_ADDRESS_SEPOLIA= -STARKNET_ADMIN_PRIVATE_KEY_SEPOLIA= -# Responsible for doing the transactions on starknet from the sequencer -STARKNET_SOLIS_ACCOUNT_ADDRESS_SEPOLIA= -STARKNET_SOLIS_ACCOUNT_PRIVATE_KEY_SEPOLIA= -# Solis accounts sepolia -# Responsible for deploying the contracts on solis sepolia -SOLIS_ADMIN_ADDRESS_SEPOLIA= -SOLIS_ADMIN_PRIVATE_KEY_SEPOLIA= +STARKNET_ACCOUNT1_ADDRESS= +STARKNET_ACCOUNT1_PRIVATE_KEY= +STARKNET_ACCOUNT2_ADDRESS= +STARKNET_ACCOUNT2_PRIVATE_KEY= -# MAINNET -# Starknet account mainnet -# Responsible for deploying the contracts on starknet -STARKNET_ADMIN_ADDRESS_MAINNET= -STARKNET_ADMIN_PRIVATE_KEY_MAINNET= -# Responsible for doing the transactions on starknet from the sequencer -STARKNET_SOLIS_ACCOUNT_ADDRESS_MAINNET= -STARKNET_SOLIS_ACCOUNT_PRIVATE_KEY_MAINNET= -# Solis accounts mainnet -# Responsible for deploying the contracts on solis sepolia -SOLIS_ADMIN_ADDRESS_MAINNET= -SOLIS_ADMIN_PRIVATE_KEY_MAINNET= +STARKNET_ARK_RECEIVER_ADDRESS= +STARKNET_ARK_RECEIVER_PRIVATE_KEY= -# Starknet RPC -# You should change the URL to the one you want to use, preferably your own and not a public one. +STARKNET_ARK_COLLECTION_RECEIVER_ADDRESS= +STARKNET_ARK_COLLECTION_RECEIVER_PRIVATE_KEY= +STARKNET_ARK_COLLECTION_2981_RECEIVER_ADDRESS= +STARKNET_ARK_COLLECTION_2981_RECEIVER_PRIVATE_KEY= + +STARKNET_LISTING_BROKER_ACCOUNT_ADDRESS= +STARKNET_LISTING_BROKER_ACCOUNT_PRIVATE_KEY= + +STARKNET_SALE_BROKER_ACCOUNT_ADDRESS= +STARKNET_SALE_BROKER_ACCOUNT_PRIVATE_KEY= + +# Network ID +STARKNET_NETWORK_ID=dev + +# Node URLs STARKNET_NODE_URL_DEV=http://localhost:5050 STARKNET_NODE_URL_SEPOLIA=https://starknet-sepolia.public.blastapi.io STARKNET_NODE_URL_MAINNET=https://starknet-mainnet.public.blastapi.io/rpc/v0_6 - -# Solis RPC -SOLIS_NODE_URL_DEV=http://0.0.0.0:7777 -SOLIS_NODE_URL_MAINNET=https://production.solis.arkproject.dev -RPC_USER=solis -RPC_PASSWORD=password - -## Demo App env -NEXT_PUBLIC_NFT_API_KEY=AY1oXgEAmF139oBoxDSomzVnHqy8ZdQ2NxLmzJ6i -NEXT_PUBLIC_NFT_API_URL=https://api.arkproject.dev -NEXT_PUBLIC_ORDERBOOK_API_URL=https://api-orderbook.arkproject.dev -# The default broker_id should be an address used to receive marketplace fees. -NEXT_PUBLIC_BROKER_ID=0x00E4769a4d2F7F69C70951A003eBA5c32707Cef3CdfB6B27cA63567f51cdd078 -# Use the corresponding contract for the network used in the example app (default is mainnet). -# The contract can be found in contracts.json in the repo root. -NEXT_PUBLIC_STARKNET_NFT_CONTRACT=0x32d99485b22f2e58c8a0206d3b3bb259997ff0db70cffd25585d7dd9a5b0546 diff --git a/.env.test b/.env.test new file mode 100644 index 000000000..ecd867c1d --- /dev/null +++ b/.env.test @@ -0,0 +1,42 @@ +# Starknet RPC URL +STARKNET_RPC_URL=http://0.0.0.0:5050 + +## starknet-devnet-rs 0.2.0 account --seed 0 +# Starknet accounts +STARKNET_ADMIN_ADDRESS_DEV=0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691 +STARKNET_ADMIN_PRIVATE_KEY_DEV=0x0000000000000000000000000000000071d7bb07b9a64f6f78ac4c816aff4da9 + +STARKNET_ACCOUNT1_ADDRESS=0x78662e7352d062084b0010068b99288486c2d8b914f6e2a55ce945f8792c8b1 +STARKNET_ACCOUNT1_PRIVATE_KEY=0x000000000000000000000000000000000e1406455b7d66b1690803be066cbe5e +STARKNET_ACCOUNT1_PUBLIC_KEY=0x007a1bb2744a7dd29bffd44341dbd78008adb4bc11733601e7eddff322ada9cb + +STARKNET_ACCOUNT2_ADDRESS=0x49dfb8ce986e21d354ac93ea65e6a11f639c1934ea253e5ff14ca62eca0f38e +STARKNET_ACCOUNT2_PRIVATE_KEY=0x00000000000000000000000000000000a20a02f0ac53692d144b20cb371a60d7 +STARKNET_ACCOUNT2_PUBLIC_KEY=0x00b8fd4ddd415902d96f61b7ad201022d495997c2dff8eb9e0eb86253e30fabc + +STARKNET_ARK_RECEIVER_ADDRESS=0x4f348398f859a55a0c80b1446c5fdc37edb3a8478a32f10764659fc241027d3 +STARKNET_ARK_RECEIVER_PRIVATE_KEY=0x00000000000000000000000000000000a641611c17d4d92bd0790074e34beeb7 + +STARKNET_ARK_COLLECTION_RECEIVER_ADDRESS=0xd513de92c16aa42418cf7e5b60f8022dbee1b4dfd81bcf03ebee079cfb5cb5 +STARKNET_ARK_COLLECTION_RECEIVER_PRIVATE_KEY=0x000000000000000000000000000000005b4ac23628a5749277bcabbf4726b025 + +STARKNET_ARK_COLLECTION_2981_RECEIVER_ADDRESS=0x1e8c6c17efa3a047506c0b1610bd188aa3e3dd6c5d9227549b65428de24de78 +STARKNET_ARK_COLLECTION_2981_RECEIVER_PRIVATE_KEY=0x00000000000000000000000000000000836203aceb0e9b0066138c321dda5ae6 + +STARKNET_LISTING_BROKER_ACCOUNT_ADDRESS=0x557ba9ef60b52dad611d79b60563901458f2476a5c1002a8b4869fcb6654c7e +STARKNET_LISTING_BROKER_ACCOUNT_PRIVATE_KEY=0x0000000000000000000000000000000015b5e3013d752c909988204714f1ff35 + +STARKNET_SALE_BROKER_ACCOUNT_ADDRESS=0x3736286f1050d4ba816b4d56d15d80ca74c1752c4e847243f1da726c36e06f +STARKNET_SALE_BROKER_ACCOUNT_PRIVATE_KEY=0x00000000000000000000000000000000a56597ba3378fa9e6440ea9ae0cf2865 + +SOLIS_ADMIN_ADDRESS_DEV=0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca +SOLIS_ADMIN_PRIVATE_KEY_DEV=0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a +SOLIS_ADMIN_PUBLIC_KEY_DEV=0x640466ebd2ce505209d3e5c4494b4276ed8f1cde764d757eb48831961f7cdea + +SOLIS_ADMIN_ADDRESS=0x6b86e40118f29ebe393a75469b4d926c7a44c2e2681b6d319520b7c1156d114 +SOLIS_ADMIN_PRIVATE_KEY=0x1c9053c053edf324aec366a34c6901b1095b07af69495bffec7d7fe21effb1b + +# Starknet network +STARKNET_NETWORK_ID=dev +# Solis network +SOLIS_NETWORK_ID=dev diff --git a/.github/actions/install-snforge/action.yml b/.github/actions/install-snforge/action.yml new file mode 100644 index 000000000..eebf800ea --- /dev/null +++ b/.github/actions/install-snforge/action.yml @@ -0,0 +1,36 @@ +name: "Install contract dependencies" +description: "Install dependencies for smart contract" + +env: + SCARB_VERSION: 2.7.1 + STARKNET_FOUNDRY_VERSION: 0.30.0 + +runs: + using: "composite" + steps: + - name: Install universal sierra compiler + shell: bash + run: | + curl -L https://raw.githubusercontent.com/software-mansion/universal-sierra-compiler/master/scripts/install.sh | sh + echo "/root/.local/bin" >> ${GITHUB_PATH} + + - name: Check universal sierra compiler version + shell: bash + run: universal-sierra-compiler --version + + - name: Setup Scarb + uses: software-mansion/setup-scarb@v1 + with: + scarb-version: ${{ env.SCARB_VERSION }} + + - name: Setup Starknet Foundry + uses: foundry-rs/setup-snfoundry@v3 + with: + starknet-foundry-version: ${{ env.STARKNET_FOUNDRY_VERSION }} + + - name: Set Up Stable Rust Toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + diff --git a/.github/workflows/arkproject-contracts.yml b/.github/workflows/arkproject-contracts.yml index 99bf305e3..edec856a8 100644 --- a/.github/workflows/arkproject-contracts.yml +++ b/.github/workflows/arkproject-contracts.yml @@ -10,47 +10,92 @@ on: paths: - "contracts/**" +env: + SCARB_VERSION: 2.7.1 + STARKNET_DEVNET_VERSION: 0.2.0 + DEVNET_DUMP_PATH: /devnet-dump.json + DEVNET_DEPLOYMENT_DUMP_PATH: /tmp/devnet-deployment-dump.json + DEVNET_SET_FEES_DUMP_PATH: /tmp/devnet-set-fees-dump.json jobs: fmt: runs-on: ubuntu-latest name: Cairo formatting steps: - name: Checkout Repository - uses: actions/checkout@v3 - - name: Install universal sierra compiler - run: curl -L https://raw.githubusercontent.com/software-mansion/universal-sierra-compiler/master/scripts/install.sh | sh + uses: actions/checkout@v4 + - name: Setup Scarb uses: software-mansion/setup-scarb@v1 with: - scarb-version: 2.5.4 + scarb-version: ${{ env.SCARB_VERSION }} + - name: Check Scarb Formatting run: cd contracts && scarb fmt --check - test: + + forge-test: runs-on: ubuntu-latest name: Cairo starknet foundry tests steps: - name: Checkout Repository - uses: actions/checkout@v3 - - name: Install universal sierra compiler - run: curl -L https://raw.githubusercontent.com/software-mansion/universal-sierra-compiler/master/scripts/install.sh | sh - - name: Setup Scarb - uses: software-mansion/setup-scarb@v1 - with: - scarb-version: 2.5.4 + uses: actions/checkout@v4 - - name: Setup Starknet Foundry - uses: foundry-rs/setup-snfoundry@v2 - with: - starknet-foundry-version: 0.18.0 + - name: Install starknet foundry & dependencies + uses: ./.github/actions/install-snforge + + - name: Test contracts + run: cd contracts && snforge test + + devnet-test: + runs-on: ubuntu-latest + name: Running SDK test with starknet-devnet + # needs: forge-test + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Install starknet foundry & dependencies + uses: ./.github/actions/install-snforge + + - name: Build smart contracts + run: cd contracts && scarb build --workspace + + - name: Run starknet-devnet as a background process + run: | + docker run -d --rm --name starknet-devnet \ + -p 5050:5050 \ + shardlabs/starknet-devnet-rs:${STARKNET_DEVNET_VERSION} \ + --seed 0 --dump-path $DEVNET_DUMP_PATH --dump-on exit --state-archive-capacity full + sleep 3 # Wait for 3 seconds for the Docker container to initialize + + - name: Install SDK dependencies + uses: ./.github/actions/install-dependencies + + - name: Setup environment for devnet + run: cp .env.test .env + + - name: Deploy smart contract + run: pnpm deploy:starknet:local + + - name: Store devnet state after contract deployment + run: | + curl -H "Content-type: application/json" \ + -X POST http://localhost:5050/dump \ + -d '{"path": "$DEVNET_DEPLOYMENT_DUMP_PATH"}' - - name: Test ark_common contracts - run: cd contracts/ark_common && snforge test + - name: Run fulfill auction test + run: | + pnpm test --filter=core -- tests/fulfillAuction.test.ts - - name: Test ark_orderbook contracts - run: cd contracts/ark_orderbook && snforge test + - name: Restore devnet state + run: | + curl -H "Content-type: application/json" \ + -X POST http://localhost:5050/load \ + -d '{"path": "$DEVNET_DEPLOYMENT_DUMP_PATH"}' - - name: Test ark_starknet contracts - run: cd contracts/ark_starknet && snforge test + - name: Run SDK test + run: | + pnpm test --filter=core - - name: Test ark_tokens contracts - run: cd contracts/ark_tokens && snforge test + - name: Stop starknet-devnet container + if: always() + run: docker stop starknet-devnet diff --git a/Cargo.lock b/Cargo.lock index cdd1ffde8..cd4b96a9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,30 +28,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "ahash" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "getrandom", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" version = "1.1.2" @@ -61,21 +37,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "allocator-api2" version = "0.2.16" @@ -83,4083 +44,1612 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] -name = "alloy-consensus" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" -dependencies = [ - "alloy-eips", - "alloy-primitives", - "alloy-rlp", - "alloy-serde", - "c-kzg", - "serde", - "sha2", -] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" [[package]] -name = "alloy-contract" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" -dependencies = [ - "alloy-dyn-abi", - "alloy-json-abi", - "alloy-network", - "alloy-primitives", - "alloy-provider", - "alloy-rpc-types", - "alloy-sol-types", - "alloy-transport", - "futures", - "futures-util", - "thiserror", +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", ] [[package]] -name = "alloy-dyn-abi" -version = "0.7.4" +name = "anstream" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8425a283510106b1a6ad25dd4bb648ecde7da3fd2baeb9400a85ad62f51ec90b" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ - "alloy-json-abi", - "alloy-primitives", - "alloy-sol-type-parser", - "alloy-sol-types", - "const-hex", - "itoa", - "serde", - "serde_json", - "winnow 0.6.8", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", ] [[package]] -name = "alloy-eips" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "alloy-serde", - "c-kzg", - "once_cell", - "serde", -] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] -name = "alloy-genesis" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ - "alloy-primitives", - "alloy-serde", - "serde", - "serde_json", + "utf8parse", ] [[package]] -name = "alloy-json-abi" -version = "0.7.4" +name = "anstyle-query" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30946aa6173020259055a44971f5cf40a7d76c931d209caeb51b333263df4f" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "alloy-primitives", - "alloy-sol-type-parser", - "serde", - "serde_json", + "windows-sys 0.52.0", ] [[package]] -name = "alloy-json-rpc" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ - "alloy-primitives", - "serde", - "serde_json", - "thiserror", - "tracing", + "anstyle", + "windows-sys 0.52.0", ] [[package]] -name = "alloy-network" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-json-rpc", - "alloy-primitives", - "alloy-rpc-types", - "alloy-signer", - "alloy-sol-types", - "async-trait", - "futures-utils-wasm", - "thiserror", -] +name = "anyhow" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] -name = "alloy-primitives" -version = "0.7.4" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8aa973e647ec336810a9356af8aea787249c9d00b1525359f3db29a68d231b" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ - "alloy-rlp", - "bytes", - "cfg-if", - "const-hex", - "derive_more", - "hex-literal", - "itoa", - "k256", - "keccak-asm", - "proptest", - "rand", - "ruint", - "serde", - "tiny-keccak", -] - -[[package]] -name = "alloy-provider" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" -dependencies = [ - "alloy-eips", - "alloy-json-rpc", - "alloy-network", - "alloy-primitives", - "alloy-rpc-client", - "alloy-rpc-types", - "alloy-rpc-types-trace", - "alloy-transport", - "alloy-transport-http", - "async-stream", - "async-trait", - "auto_impl", - "dashmap", - "futures", - "futures-utils-wasm", - "lru 0.12.3", - "reqwest 0.12.4", - "serde_json", - "tokio", - "tracing", - "url", + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", ] [[package]] -name = "alloy-rlp" -version = "0.3.4" +name = "ark-ff-asm" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "alloy-rlp-derive", - "arrayvec", - "bytes", + "quote", + "syn 1.0.109", ] [[package]] -name = "alloy-rlp-derive" -version = "0.3.4" +name = "ark-ff-macros" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ + "num-bigint", + "num-traits", "proc-macro2", "quote", - "syn 2.0.64", + "syn 1.0.109", ] [[package]] -name = "alloy-rpc-client" +name = "ark-metadata" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" dependencies = [ - "alloy-json-rpc", - "alloy-transport", - "alloy-transport-http", - "futures", - "pin-project", - "reqwest 0.12.4", + "anyhow", + "ark-starknet", + "async-trait", + "base64 0.21.5", + "chrono", + "dotenv", + "mockall", + "num-bigint", + "reqwest", "serde", + "serde_derive", "serde_json", + "starknet 0.10.0", + "thiserror 1.0.51", "tokio", - "tokio-stream", - "tower", "tracing", - "url", -] - -[[package]] -name = "alloy-rpc-types" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-genesis", - "alloy-primitives", - "alloy-rlp", - "alloy-serde", - "alloy-sol-types", - "itertools 0.12.0", - "serde", - "serde_json", - "thiserror", + "urlencoding", ] [[package]] -name = "alloy-rpc-types-trace" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ - "alloy-primitives", - "alloy-rpc-types", - "alloy-serde", - "serde", - "serde_json", + "ark-std", + "digest", + "num-bigint", ] [[package]] -name = "alloy-serde" +name = "ark-starknet" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" dependencies = [ - "alloy-primitives", - "serde", - "serde_json", + "anyhow", + "async-trait", + "mockall", + "num-bigint", + "num-traits", + "regex", + "starknet 0.10.0", + "thiserror 1.0.51", + "tokio", + "tracing", + "tracing-subscriber", + "url", ] [[package]] -name = "alloy-signer" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ - "alloy-primitives", - "async-trait", - "auto_impl", - "elliptic-curve", - "k256", - "thiserror", + "num-traits", + "rand", ] [[package]] -name = "alloy-signer-wallet" +name = "arkproject" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" dependencies = [ - "alloy-consensus", - "alloy-network", - "alloy-primitives", - "alloy-signer", + "anyhow", + "ark-metadata", + "ark-starknet", "async-trait", - "k256", - "rand", - "thiserror", + "diri", + "futures", + "log", + "mockall", + "orderbook", + "pontos", + "sana", + "sqlx", + "starknet 0.7.0", + "tokio", + "tracing", + "tracing-log 0.1.4", + "tracing-subscriber", + "url", ] [[package]] -name = "alloy-sol-macro" +name = "arrayvec" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dbd17d67f3e89478c8a634416358e539e577899666c927bc3d2b1328ee9b6ca" -dependencies = [ - "alloy-sol-macro-expander", - "alloy-sol-macro-input", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.64", -] +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] -name = "alloy-sol-macro-expander" -version = "0.7.4" +name = "async-trait" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6da95adcf4760bb4b108fefa51d50096c5e5fdd29ee72fed3e86ee414f2e34" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ - "alloy-json-abi", - "alloy-sol-macro-input", - "const-hex", - "heck 0.4.1", - "indexmap 2.1.0", - "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.64", - "syn-solidity", - "tiny-keccak", + "syn 2.0.100", ] [[package]] -name = "alloy-sol-macro-input" -version = "0.7.4" +name = "atoi" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c8da04c1343871fb6ce5a489218f9c85323c8340a36e9106b5fc98d4dd59d5" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ - "alloy-json-abi", - "const-hex", - "dunce", - "heck 0.5.0", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.64", - "syn-solidity", + "num-traits", ] [[package]] -name = "alloy-sol-type-parser" -version = "0.7.4" +name = "auto_impl" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368cae4dc052cad1d8f72eb2ae0c38027116933eeb49213c200a9e9875f208d7" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "winnow 0.6.8", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "alloy-sol-types" -version = "0.7.4" +name = "autocfg" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a64d2d2395c1ac636b62419a7b17ec39031d6b2367e66e9acbf566e6055e9c" -dependencies = [ - "alloy-json-abi", - "alloy-primitives", - "alloy-sol-macro", - "const-hex", - "serde", -] +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] -name = "alloy-transport" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ - "alloy-json-rpc", - "base64 0.22.1", - "futures-util", - "futures-utils-wasm", - "serde", - "serde_json", - "thiserror", - "tokio", - "tower", - "url", - "wasm-bindgen-futures", + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", ] [[package]] -name = "alloy-transport-http" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce#5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" -dependencies = [ - "alloy-json-rpc", - "alloy-transport", - "reqwest 0.12.4", - "serde_json", - "tower", - "url", -] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] -name = "android-tzdata" -version = "0.1.1" +name = "base64" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] -name = "android_system_properties" -version = "0.1.5" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "anstream" -version = "0.6.14" +name = "base64ct" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bigdecimal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", + "num-bigint", + "num-integer", + "num-traits", + "serde", ] [[package]] -name = "anstyle" -version = "1.0.4" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "anstyle-parse" -version = "0.2.3" +name = "bitflags" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" dependencies = [ - "utf8parse", + "serde", ] [[package]] -name = "anstyle-query" -version = "1.0.2" +name = "bitvec" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "windows-sys 0.52.0", + "funty", + "radium", + "tap", + "wyz", ] [[package]] -name = "anstyle-wincon" -version = "3.0.2" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "anstyle", - "windows-sys 0.52.0", + "generic-array", ] [[package]] -name = "anyhow" -version = "1.0.83" +name = "bumpalo" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] -name = "ark-ec" -version = "0.4.2" +name = "byte-slice-cast" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" -dependencies = [ - "ark-ff 0.4.2", - "ark-poly", - "ark-serialize 0.4.2", - "ark-std 0.4.0", - "derivative", - "hashbrown 0.13.1", - "itertools 0.10.5", - "num-traits 0.2.17", - "zeroize", -] +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] -name = "ark-ff" -version = "0.3.0" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" -dependencies = [ - "ark-ff-asm 0.3.0", - "ark-ff-macros 0.3.0", - "ark-serialize 0.3.0", - "ark-std 0.3.0", - "derivative", - "num-bigint", - "num-traits 0.2.17", - "paste", - "rustc_version 0.3.3", - "zeroize", -] +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] -name = "ark-ff" -version = "0.4.2" +name = "bytes" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm 0.4.2", - "ark-ff-macros 0.4.2", - "ark-serialize 0.4.2", - "ark-std 0.4.0", - "derivative", - "digest 0.10.7", - "itertools 0.10.5", - "num-bigint", - "num-traits 0.2.17", - "paste", - "rustc_version 0.4.0", - "zeroize", -] +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] -name = "ark-ff-asm" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +name = "cainome" +version = "0.2.3" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ - "quote", - "syn 1.0.109", + "anyhow", + "async-trait", + "cainome-cairo-serde", + "cainome-parser", + "cainome-rs", + "cainome-rs-macro", + "camino", + "clap", + "clap_complete", + "convert_case", + "serde", + "serde_json", + "starknet 0.12.0", + "starknet-types-core", + "thiserror 1.0.51", + "tracing", + "tracing-subscriber", + "url", ] [[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +name = "cainome-cairo-serde" +version = "0.1.0" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ - "quote", - "syn 1.0.109", + "serde", + "starknet 0.12.0", + "thiserror 1.0.51", ] [[package]] -name = "ark-ff-macros" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +name = "cainome-parser" +version = "0.1.0" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ - "num-bigint", - "num-traits 0.2.17", + "convert_case", "quote", - "syn 1.0.109", + "serde_json", + "starknet 0.12.0", + "syn 2.0.100", + "thiserror 1.0.51", ] [[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +name = "cainome-rs" +version = "0.1.0" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ - "num-bigint", - "num-traits 0.2.17", + "anyhow", + "cainome-cairo-serde", + "cainome-parser", + "camino", + "prettyplease", "proc-macro2", "quote", - "syn 1.0.109", + "serde_json", + "starknet 0.12.0", + "syn 2.0.100", + "thiserror 1.0.51", ] [[package]] -name = "ark-metadata" +name = "cainome-rs-macro" version = "0.1.0" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ "anyhow", - "ark-starknet", - "async-trait", - "base64 0.21.5", - "chrono", - "dotenv", - "mockall", - "num-bigint", - "reqwest 0.11.22", - "serde", - "serde_derive", + "cainome-cairo-serde", + "cainome-parser", + "cainome-rs", + "proc-macro-error", + "proc-macro2", + "quote", "serde_json", - "starknet 0.10.0", - "thiserror", - "tokio", - "tracing", - "urlencoding", + "starknet 0.12.0", + "syn 2.0.100", + "thiserror 1.0.51", ] [[package]] -name = "ark-poly" -version = "0.4.2" +name = "camino" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ - "ark-ff 0.4.2", - "ark-serialize 0.4.2", - "ark-std 0.4.0", - "derivative", - "hashbrown 0.13.1", + "serde", ] [[package]] -name = "ark-secp256k1" -version = "0.4.0" +name = "cc" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c02e954eaeb4ddb29613fee20840c2bbc85ca4396d53e33837e11905363c5f2" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ - "ark-ec", - "ark-ff 0.4.2", - "ark-std 0.4.0", + "shlex", ] [[package]] -name = "ark-secp256r1" -version = "0.4.0" +name = "cfg-if" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3975a01b0a6e3eae0f72ec7ca8598a6620fc72fa5981f6f5cca33b7cd788f633" -dependencies = [ - "ark-ec", - "ark-ff 0.4.2", - "ark-std 0.4.0", -] +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "ark-serialize" -version = "0.3.0" +name = "chrono" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ - "ark-std 0.3.0", - "digest 0.9.0", + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.48.5", ] [[package]] -name = "ark-serialize" -version = "0.4.2" +name = "cipher" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "ark-serialize-derive", - "ark-std 0.4.0", - "digest 0.10.7", - "num-bigint", + "crypto-common", + "inout", ] [[package]] -name = "ark-serialize-derive" -version = "0.4.2" +name = "clap" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "clap_builder", + "clap_derive", ] [[package]] -name = "ark-starknet" -version = "0.1.0" +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ - "anyhow", - "async-trait", - "mockall", - "num-bigint", - "num-traits 0.2.17", - "regex", - "starknet 0.10.0", - "thiserror", - "tokio", - "tracing", - "tracing-subscriber", - "url", + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", ] [[package]] -name = "ark-std" -version = "0.3.0" +name = "clap_complete" +version = "4.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +checksum = "b5a2d6eec27fce550d708b2be5d798797e5a55b246b323ef36924a0001996352" dependencies = [ - "num-traits 0.2.17", - "rand", + "clap", ] [[package]] -name = "ark-std" -version = "0.4.0" +name = "clap_derive" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "num-traits 0.2.17", - "rand", -] - -[[package]] -name = "arkproject" -version = "0.1.0" -dependencies = [ - "alloy-primitives", - "alloy-sol-types", - "anyhow", - "ark-metadata", - "ark-starknet", - "async-trait", - "diri", - "futures", - "log", - "mockall", - "pontos", - "sana", - "sqlx", - "starknet 0.7.0", - "tokio", - "tracing", - "tracing-log 0.1.4", - "tracing-subscriber", - "url", + "heck", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "ascii-canvas" -version = "3.0.0" +name = "clap_lex" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" -dependencies = [ - "term", -] +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] -name = "assert_matches" -version = "1.5.0" +name = "colorchoice" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] -name = "async-compression" -version = "0.4.5" +name = "concurrent-queue" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc2d0cfb2a7388d34f590e76686704c494ed7aaceed62ee1ba35cbf363abc2a5" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", - "zstd", - "zstd-safe", + "crossbeam-utils", ] [[package]] -name = "async-stream" -version = "0.3.5" +name = "const-oid" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] -name = "async-stream-impl" -version = "0.3.5" +name = "convert_case" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.64", + "unicode-segmentation", ] [[package]] -name = "async-trait" -version = "0.1.74" +name = "core-foundation" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.64", + "core-foundation-sys", + "libc", ] [[package]] -name = "atoi" -version = "2.0.0" +name = "core-foundation-sys" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" -dependencies = [ - "num-traits 0.2.17", -] +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] -name = "atomic-write-file" -version = "0.1.2" +name = "cpufeatures" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ - "nix", - "rand", + "libc", ] [[package]] -name = "auto_impl" -version = "1.2.0" +name = "crc" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.64", + "crc-catalog", ] [[package]] -name = "autocfg" -version = "1.1.0" +name = "crc-catalog" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] -name = "backtrace" -version = "0.3.69" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "addr2line", - "cc", "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", ] [[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.13.1" +name = "crossbeam-queue" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "b9bcf5bdbfdd6030fb4a1c497b5d5fc5921aa2f60d359a17e249c0e6df3de153" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] [[package]] -name = "base64" -version = "0.21.5" +name = "crossbeam-utils" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" +dependencies = [ + "cfg-if", +] [[package]] -name = "base64" -version = "0.22.1" +name = "crunchy" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] -name = "base64ct" -version = "1.6.0" +name = "crypto-bigint" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "subtle", + "zeroize", +] [[package]] -name = "beef" -version = "0.5.2" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "serde", + "generic-array", + "typenum", ] [[package]] -name = "bigdecimal" -version = "0.3.1" +name = "ctr" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "num-bigint", - "num-integer", - "num-traits 0.2.17", - "serde", + "cipher", ] [[package]] -name = "bincode" -version = "2.0.0-rc.3" +name = "darling" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ - "serde", + "darling_core", + "darling_macro", ] [[package]] -name = "bindgen" -version = "0.68.1" +name = "darling_core" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ - "bitflags 2.4.1", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", + "fnv", + "ident_case", "proc-macro2", "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.64", + "strsim 0.10.0", + "syn 2.0.100", ] [[package]] -name = "bit-set" -version = "0.5.3" +name = "darling_macro" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ - "bit-vec", + "darling_core", + "quote", + "syn 2.0.100", ] [[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.1" +name = "der" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ - "serde", + "const-oid", + "pem-rfc7468", + "zeroize", ] [[package]] -name = "bitvec" -version = "1.0.1" +name = "deranged" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" dependencies = [ - "funty", - "radium", - "tap", - "wyz", + "powerfmt", + "serde", ] [[package]] -name = "block-buffer" -version = "0.9.0" +name = "derivative" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "generic-array", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "generic-array", + "block-buffer", + "const-oid", + "crypto-common", + "subtle", ] [[package]] -name = "blockifier" -version = "0.6.0-rc.2" -source = "git+https://github.com/dojoengine/blockifier?rev=935292bb#935292bb37843e4deb69f0da075dec0e5a15378b" +name = "diri" +version = "0.1.0" dependencies = [ "anyhow", - "ark-ec", - "ark-ff 0.4.2", - "ark-secp256k1", - "ark-secp256r1", - "cached", - "cairo-felt", - "cairo-lang-casm", - "cairo-lang-runner", - "cairo-lang-starknet-classes", - "cairo-lang-utils", - "cairo-vm", - "derive_more", - "indexmap 2.1.0", - "itertools 0.10.5", - "keccak", + "async-trait", + "clap", + "dotenv", + "env_logger", + "futures", "log", "num-bigint", - "num-integer", - "num-traits 0.2.17", - "once_cell", - "phf", - "rstest", + "num-traits", + "orderbook", + "regex", "serde", "serde_json", - "sha3", - "starknet-crypto 0.5.2", - "starknet_api", - "strum 0.24.1", - "strum_macros 0.24.3", - "thiserror", + "starknet 0.12.0", + "starknet-types-core", + "thiserror 1.0.51", + "tokio", + "tracing", + "tracing-subscriber", + "url", ] [[package]] -name = "blst" -version = "0.3.11" +name = "dotenv" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" -dependencies = [ - "cc", - "glob", - "threadpool", - "zeroize", -] +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] -name = "brotli" -version = "3.4.0" +name = "dotenvy" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] -name = "brotli-decompressor" -version = "2.5.1" +name = "downcast" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] -name = "bstr" -version = "1.8.0" +name = "either" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" dependencies = [ - "memchr", "serde", ] [[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "bytemuck" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.5.0" +name = "encoding_rs" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ - "serde", + "cfg-if", ] [[package]] -name = "c-kzg" -version = "1.0.2" +name = "env_logger" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf100c4cea8f207e883ff91ca886d621d8a166cb04971dfaa9bb8fd99ed95df" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ - "blst", - "cc", - "glob", - "hex", - "libc", - "serde", + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", ] [[package]] -name = "cached" -version = "0.44.0" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b195e4fbc4b6862bbd065b991a34750399c119797efff72492f28a5864de8700" -dependencies = [ - "async-trait", - "cached_proc_macro", - "cached_proc_macro_types", - "futures", - "hashbrown 0.13.1", - "instant", - "once_cell", - "thiserror", - "tokio", -] +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "cached_proc_macro" -version = "0.17.0" +name = "errno" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b48814962d2fd604c50d2b9433c2a41a0ab567779ee2c02f7fba6eca1221f082" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ - "cached_proc_macro_types", - "darling 0.14.4", - "proc-macro2", - "quote", - "syn 1.0.109", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "cached_proc_macro_types" -version = "0.1.0" +name = "etcetera" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" - -[[package]] -name = "cainome" -version = "0.1.5" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.8#e79deabeb989f73100c0b2e6a1fe5427858e40a8" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" dependencies = [ - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.1.8)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.1.8)", - "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.1.8)", + "cfg-if", + "home", + "windows-sys 0.48.0", ] [[package]] -name = "cainome" -version = "0.2.3" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.6#07ba9c91baa2f6aa2bc850b6699ffc2266be9a13" +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" dependencies = [ - "anyhow", - "async-trait", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.6)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.6)", - "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.6)", - "cainome-rs-macro", - "camino", - "clap", - "clap_complete", - "convert_case 0.6.0", + "aes", + "ctr", + "digest", + "hex", + "hmac", + "pbkdf2", + "rand", + "scrypt", "serde", "serde_json", - "starknet 0.9.0", - "thiserror", - "tracing", - "tracing-subscriber", - "url", -] - -[[package]] -name = "cainome-cairo-serde" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.8#e79deabeb989f73100c0b2e6a1fe5427858e40a8" -dependencies = [ - "starknet 0.8.0", - "thiserror", -] - -[[package]] -name = "cainome-cairo-serde" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.6#07ba9c91baa2f6aa2bc850b6699ffc2266be9a13" -dependencies = [ - "starknet 0.9.0", - "thiserror", -] - -[[package]] -name = "cainome-parser" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.8#e79deabeb989f73100c0b2e6a1fe5427858e40a8" -dependencies = [ - "quote", - "serde_json", - "starknet 0.8.0", - "syn 2.0.64", - "thiserror", -] - -[[package]] -name = "cainome-parser" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.6#07ba9c91baa2f6aa2bc850b6699ffc2266be9a13" -dependencies = [ - "convert_case 0.6.0", - "quote", - "serde_json", - "starknet 0.9.0", - "syn 2.0.64", - "thiserror", -] - -[[package]] -name = "cainome-rs" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.8#e79deabeb989f73100c0b2e6a1fe5427858e40a8" -dependencies = [ - "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.1.8)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.1.8)", - "proc-macro2", - "quote", - "serde_json", - "starknet 0.8.0", - "syn 2.0.64", - "thiserror", -] - -[[package]] -name = "cainome-rs" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.6#07ba9c91baa2f6aa2bc850b6699ffc2266be9a13" -dependencies = [ - "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.6)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.6)", - "proc-macro2", - "quote", - "serde_json", - "starknet 0.9.0", - "syn 2.0.64", - "thiserror", -] - -[[package]] -name = "cainome-rs-macro" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.6#07ba9c91baa2f6aa2bc850b6699ffc2266be9a13" -dependencies = [ - "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.6)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.6)", - "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.6)", - "proc-macro2", - "quote", - "serde_json", - "starknet 0.9.0", - "syn 2.0.64", - "thiserror", + "sha2", + "sha3", + "thiserror 1.0.51", + "uuid", ] [[package]] -name = "cairo-felt" -version = "0.9.1" -source = "git+https://github.com/dojoengine/cairo-rs.git?rev=1031381#10313816b4ba7891e3c8ba90f6d0068a9149d682" +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" dependencies = [ - "lazy_static", - "num-bigint", - "num-integer", - "num-traits 0.2.17", - "serde", + "crunchy", + "fixed-hash", + "impl-rlp", + "impl-serde", + "tiny-keccak", ] [[package]] -name = "cairo-lang-casm" -version = "2.6.3" +name = "ethereum-types" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d9c31baeb6b52586b5adc88f01e90f86389d63d94363c562de5c79352e545b" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" dependencies = [ - "cairo-lang-utils", - "indoc", - "num-bigint", - "num-traits 0.2.17", - "parity-scale-codec", - "serde", + "ethbloom", + "fixed-hash", + "impl-rlp", + "impl-serde", + "primitive-types", + "uint", ] [[package]] -name = "cairo-lang-compiler" -version = "2.6.3" +name = "event-listener" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7148cb2d72a3db24a6d2ef2b2602102cc5099cb9f6b913e5047fb009cb3a22a1" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ - "anyhow", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-project", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-syntax", - "cairo-lang-utils", - "salsa", - "smol_str", - "thiserror", + "concurrent-queue", + "parking", + "pin-project-lite", ] [[package]] -name = "cairo-lang-debug" -version = "2.6.3" +name = "fastrand" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a761eb8e31ea65a2dd45f729c74f1770315f97124dad93d1f6853a10d460c6b" -dependencies = [ - "cairo-lang-utils", -] +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] -name = "cairo-lang-defs" -version = "2.6.3" +name = "finl_unicode" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d60bc5d72fe7a95ba34e041dcbdf1cf3bfccb87008a515514b74913fa8ff05" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.11.0", - "salsa", - "smol_str", -] +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" [[package]] -name = "cairo-lang-diagnostics" -version = "2.6.3" +name = "fixed-hash" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356089e1b0a0ba9e115566191745613b3806a20259ad76764df82ab534d5412a" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", - "itertools 0.11.0", + "byteorder", + "rand", + "rustc-hex", + "static_assertions", ] [[package]] -name = "cairo-lang-eq-solver" -version = "2.6.3" +name = "flate2" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc43246cc2e5afd5a028bcdd63876ac3f8b1f4fb3ff785daaa0f0fbb51c9d906" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ - "cairo-lang-utils", - "good_lp", + "crc32fast", + "miniz_oxide", ] [[package]] -name = "cairo-lang-filesystem" -version = "2.6.3" +name = "flume" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bcb9a4a40e53fa099774bd08bbcc3430f51213cc7fb1b50c2e9d01155731798" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ - "cairo-lang-debug", - "cairo-lang-utils", - "path-clean", - "salsa", - "serde", - "smol_str", + "futures-core", + "futures-sink", + "spin 0.9.8", ] [[package]] -name = "cairo-lang-lowering" -version = "2.6.3" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba60e1e2477aa0f610ccf29189097d580464607c94b51741e1c18e64d6cee5f" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-proc-macros", - "cairo-lang-semantic", - "cairo-lang-syntax", - "cairo-lang-utils", - "id-arena", - "itertools 0.11.0", - "log", - "num-bigint", - "num-traits 0.2.17", - "once_cell", - "salsa", - "smol_str", -] +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "cairo-lang-parser" -version = "2.6.3" +name = "foldhash" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f16ba1535e0cc5e79c2eff6592859bbdac03dc53d4dcdd26dbdbc04a77c3f5c" -dependencies = [ - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-syntax", - "cairo-lang-syntax-codegen", - "cairo-lang-utils", - "colored", - "itertools 0.11.0", - "num-bigint", - "num-traits 0.2.17", - "salsa", - "smol_str", - "unescaper", -] +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] -name = "cairo-lang-plugins" -version = "2.6.3" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81c8cf6e0ee3d6b19429cc1663738b22f1ecea7d51bf7452e8e1086f08798baf" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "indent", - "indoc", - "itertools 0.11.0", - "salsa", - "smol_str", + "foreign-types-shared", ] [[package]] -name = "cairo-lang-proc-macros" -version = "2.6.3" +name = "foreign-types-shared" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67f9da66325ce7ed6c002360f26106fe79deb9f8a2fca30abdbb8d388da7bb46" -dependencies = [ - "cairo-lang-debug", - "quote", - "syn 2.0.64", -] +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] -name = "cairo-lang-project" -version = "2.6.3" +name = "form_urlencoded" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e198af1ab3d05c7fb8b6a9a7a2e9bce245a6c855df5f770b751d29874a23b152" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "cairo-lang-filesystem", - "cairo-lang-utils", - "serde", - "smol_str", - "thiserror", - "toml", -] - -[[package]] -name = "cairo-lang-runner" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf211f5431e2a6f4802b1b6483bf8e998e506a3be5369ed54a8807aae6e4dbf" -dependencies = [ - "ark-ff 0.4.2", - "ark-secp256k1", - "ark-secp256r1", - "ark-std 0.4.0", - "cairo-felt", - "cairo-lang-casm", - "cairo-lang-lowering", - "cairo-lang-sierra", - "cairo-lang-sierra-ap-change", - "cairo-lang-sierra-generator", - "cairo-lang-sierra-to-casm", - "cairo-lang-sierra-type-size", - "cairo-lang-starknet", - "cairo-lang-utils", - "cairo-vm", - "itertools 0.11.0", - "keccak", - "num-bigint", - "num-integer", - "num-traits 0.2.17", - "smol_str", - "starknet-crypto 0.6.2", - "thiserror", -] - -[[package]] -name = "cairo-lang-semantic" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7df81521c2125e3e95b683cc99374db1aebd7ddb317c5ca3dd92a235a9eb13" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-plugins", - "cairo-lang-proc-macros", - "cairo-lang-syntax", - "cairo-lang-utils", - "id-arena", - "indoc", - "itertools 0.11.0", - "num-bigint", - "num-traits 0.2.17", - "once_cell", - "salsa", - "smol_str", -] - -[[package]] -name = "cairo-lang-sierra" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07da3ca1434c62a7cc7cd77d2941ef47a1c23b37325781b59407b78d8c61d863" -dependencies = [ - "anyhow", - "cairo-felt", - "cairo-lang-utils", - "const-fnv1a-hash", - "convert_case 0.6.0", - "derivative", - "itertools 0.11.0", - "lalrpop", - "lalrpop-util", - "num-bigint", - "num-traits 0.2.17", - "regex", - "salsa", - "serde", - "serde_json", - "sha3", - "smol_str", - "thiserror", -] - -[[package]] -name = "cairo-lang-sierra-ap-change" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122c9055eb609a511178e3dce577de061819fd4c4c6b7452804557f76ca43bbf" -dependencies = [ - "cairo-lang-eq-solver", - "cairo-lang-sierra", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", - "itertools 0.11.0", - "num-traits 0.2.17", - "thiserror", -] - -[[package]] -name = "cairo-lang-sierra-gas" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf049d9aea65c6e38da219a3700c72f78795d11449d9adcec28047ef8d63bd23" -dependencies = [ - "cairo-lang-eq-solver", - "cairo-lang-sierra", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", - "itertools 0.11.0", - "num-traits 0.2.17", - "thiserror", -] - -[[package]] -name = "cairo-lang-sierra-generator" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e1d75e0830279ca1bd0189e3326720d6e081225f7d81ed060bbd22c6b37e980" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.11.0", - "num-traits 0.2.17", - "once_cell", - "salsa", - "smol_str", -] - -[[package]] -name = "cairo-lang-sierra-to-casm" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3c3be88c8562fbf93b0803c186e7282f6daad93576c07f61b04a591fde468f" -dependencies = [ - "assert_matches", - "cairo-felt", - "cairo-lang-casm", - "cairo-lang-sierra", - "cairo-lang-sierra-ap-change", - "cairo-lang-sierra-gas", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", - "indoc", - "itertools 0.11.0", - "num-bigint", - "num-traits 0.2.17", - "thiserror", -] - -[[package]] -name = "cairo-lang-sierra-type-size" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38da6f98c6b16945c89d2ae351c82d636ed38d3e6eb02f7c8679e3e03a63988" -dependencies = [ - "cairo-lang-sierra", - "cairo-lang-utils", -] - -[[package]] -name = "cairo-lang-starknet" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9ffa8b3b8c47138c36b1907cebb5047dfc4de29ec10ece5bd6d6853243ec50" -dependencies = [ - "anyhow", - "cairo-felt", - "cairo-lang-compiler", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-plugins", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-starknet-classes", - "cairo-lang-syntax", - "cairo-lang-utils", - "const_format", - "indent", - "indoc", - "itertools 0.11.0", - "once_cell", - "serde", - "serde_json", - "smol_str", - "thiserror", -] - -[[package]] -name = "cairo-lang-starknet-classes" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c64ae2bb00173e3a88760128bf72de356fa80eb19fa47602479063648b4003" -dependencies = [ - "cairo-felt", - "cairo-lang-casm", - "cairo-lang-sierra", - "cairo-lang-sierra-to-casm", - "cairo-lang-utils", - "convert_case 0.6.0", - "itertools 0.11.0", - "num-bigint", - "num-integer", - "num-traits 0.2.17", - "once_cell", - "serde", - "serde_json", - "sha3", - "smol_str", - "starknet-crypto 0.6.2", - "thiserror", -] - -[[package]] -name = "cairo-lang-syntax" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8262c426a57e1e5ec297db24278464841500613445e2cb1c43d5f71ad91ee8d6" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", - "num-bigint", - "num-traits 0.2.17", - "salsa", - "smol_str", - "unescaper", -] - -[[package]] -name = "cairo-lang-syntax-codegen" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e2d692eae4bb4179a4a1148fd5eb738a91653d86750c813658ffad4a99fa97" -dependencies = [ - "genco", - "xshell", -] - -[[package]] -name = "cairo-lang-utils" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf733a7cdc4166d0baf0ed8a98d9ada827daee6653b37d9326e334e53481c6d3" -dependencies = [ - "hashbrown 0.14.3", - "indexmap 2.1.0", - "itertools 0.11.0", - "num-bigint", - "num-traits 0.2.17", - "parity-scale-codec", - "schemars", - "serde", -] - -[[package]] -name = "cairo-vm" -version = "0.9.2" -source = "git+https://github.com/dojoengine/cairo-rs.git?rev=1031381#10313816b4ba7891e3c8ba90f6d0068a9149d682" -dependencies = [ - "anyhow", - "bincode", - "bitvec", - "cairo-felt", - "generic-array", - "hashbrown 0.14.3", - "hex", - "keccak", - "lazy_static", - "mimalloc", - "nom", - "num-bigint", - "num-integer", - "num-prime", - "num-traits 0.2.17", - "rand", - "serde", - "serde_json", - "sha2", - "sha3", - "starknet-crypto 0.6.2", - "starknet-curve 0.4.2", - "thiserror-no-std", -] - -[[package]] -name = "camino" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" -dependencies = [ - "serde", -] - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "jobserver", - "libc", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits 0.2.17", - "serde", - "wasm-bindgen", - "windows-targets 0.48.5", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clang-sys" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "4.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim 0.11.1", -] - -[[package]] -name = "clap_complete" -version = "4.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" -dependencies = [ - "clap", -] - -[[package]] -name = "clap_derive" -version = "4.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.64", -] - -[[package]] -name = "clap_lex" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" - -[[package]] -name = "cobs" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "colored" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" -dependencies = [ - "lazy_static", - "windows-sys 0.48.0", -] - -[[package]] -name = "common" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" -dependencies = [ - "anyhow", - "reqwest 0.11.22", - "thiserror", -] - -[[package]] -name = "console" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.45.0", -] - -[[package]] -name = "const-fnv1a-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" - -[[package]] -name = "const-hex" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" -dependencies = [ - "cfg-if", - "cpufeatures", - "hex", - "proptest", - "serde", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "const_format" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "cpufeatures" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9bcf5bdbfdd6030fb4a1c497b5d5fc5921aa2f60d359a17e249c0e6df3de153" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", -] - -[[package]] -name = "darling" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" -dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", -] - -[[package]] -name = "darling_core" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 2.0.64", -] - -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" -dependencies = [ - "darling_core 0.20.3", - "quote", - "syn 2.0.64", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.3", - "lock_api", - "once_cell", - "parking_lot_core 0.9.9", -] - -[[package]] -name = "der" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" -dependencies = [ - "powerfmt", - "serde", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case 0.4.0", - "proc-macro2", - "quote", - "rustc_version 0.4.0", - "syn 1.0.109", -] - -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "diri" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "cainome 0.1.5", - "clap", - "dotenv", - "env_logger", - "futures", - "log", - "num-bigint", - "num-traits 0.2.17", - "regex", - "serde", - "serde_json", - "starknet 0.8.0", - "thiserror", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dojo-metrics" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" -dependencies = [ - "anyhow", - "hyper 0.14.27", - "jemalloc-ctl", - "jemallocator", - "metrics", - "metrics-exporter-prometheus", - "metrics-process", - "metrics-util", - "reth-metrics-derive", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - -[[package]] -name = "downcast" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" - -[[package]] -name = "dunce" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" - -[[package]] -name = "dyn-clone" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" -dependencies = [ - "serde", -] - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest 0.10.7", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "embedded-io" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" - -[[package]] -name = "ena" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" -dependencies = [ - "log", -] - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "env_logger" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "etcetera" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" -dependencies = [ - "cfg-if", - "home", - "windows-sys 0.48.0", -] - -[[package]] -name = "eth-keystore" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" -dependencies = [ - "aes", - "ctr", - "digest 0.10.7", - "hex", - "hmac", - "pbkdf2", - "rand", - "scrypt", - "serde", - "serde_json", - "sha2", - "sha3", - "thiserror", - "uuid 0.8.2", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", -] - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "fastrlp" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core", - "subtle", -] - -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "flume" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" -dependencies = [ - "futures-core", - "futures-sink", - "spin 0.9.8", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fragile" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" - -[[package]] -name = "futures-executor" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-intrusive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot 0.12.1", -] - -[[package]] -name = "futures-io" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" - -[[package]] -name = "futures-macro" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.64", -] - -[[package]] -name = "futures-sink" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" - -[[package]] -name = "futures-task" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" - -[[package]] -name = "futures-timer" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" - -[[package]] -name = "futures-util" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "futures-utils-wasm" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" - -[[package]] -name = "genco" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d7af598790738fee616426e669360fa361273b1b9c9b7f30c92fa627605cad" -dependencies = [ - "genco-macros", - "relative-path", - "smallvec", -] - -[[package]] -name = "genco-macros" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4cf186fea4af17825116f72932fe52cce9a13bae39ff63b4dc0cfdb3fb4bde1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.64", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "globset" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", -] - -[[package]] -name = "good_lp" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa124423ded10046a849fa0ae9747c541895557f1af177e0890b09879e7e9e7d" -dependencies = [ - "fnv", - "minilp", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.11", - "indexmap 2.1.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.7", -] - -[[package]] -name = "hashbrown" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" -dependencies = [ - "ahash 0.8.6", -] - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash 0.8.6", - "allocator-api2", - "serde", -] - -[[package]] -name = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.3", -] - -[[package]] -name = "hdrhistogram" -version = "7.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" -dependencies = [ - "byteorder", - "num-traits 0.2.17", -] - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.11", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" -dependencies = [ - "bytes", - "http 1.1.0", -] - -[[package]] -name = "http-body-util" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" -dependencies = [ - "bytes", - "futures-core", - "http 1.1.0", - "http-body 1.0.0", - "pin-project-lite", -] - -[[package]] -name = "http-range-header" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 0.2.11", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.4.10", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http 0.2.11", - "hyper 0.14.27", - "rustls", - "tokio", - "tokio-rustls", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper 0.14.27", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "hyper-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "hyper 1.3.1", - "pin-project-lite", - "socket2 0.5.5", - "tokio", - "tower", - "tower-service", - "tracing", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core 0.51.1", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "id-arena" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "indent" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f1a0777d972970f204fdf8ef319f1f4f8459131636d7e3c96c5d59570d0fa6" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" -dependencies = [ - "equivalent", - "hashbrown 0.14.3", - "serde", -] - -[[package]] -name = "indoc" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", + "percent-encoding", ] [[package]] -name = "instant" -version = "0.1.12" +name = "fragile" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] +checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] -name = "ipnet" -version = "2.9.0" +name = "funty" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] -name = "iri-string" -version = "0.7.0" +name = "futures" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ - "memchr", - "serde", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "is-terminal" -version = "0.4.9" +name = "futures-channel" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", + "futures-core", + "futures-sink", ] [[package]] -name = "is_terminal_polyfill" -version = "1.70.0" +name = "futures-core" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] -name = "itertools" -version = "0.10.5" +name = "futures-executor" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ - "either", + "futures-core", + "futures-task", + "futures-util", ] [[package]] -name = "itertools" -version = "0.11.0" +name = "futures-intrusive" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ - "either", + "futures-core", + "lock_api", + "parking_lot", ] [[package]] -name = "itertools" -version = "0.12.0" +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ - "either", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "itoa" -version = "1.0.10" +name = "futures-sink" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] -name = "jemalloc-ctl" -version = "0.5.4" +name = "futures-task" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cffc705424a344c054e135d12ee591402f4539245e8bbd64e6c9eaa9458b63c" -dependencies = [ - "jemalloc-sys", - "libc", - "paste", -] +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] -name = "jemalloc-sys" -version = "0.5.4+5.3.0-patched" +name = "futures-util" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ - "cc", - "libc", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] -name = "jemallocator" -version = "0.5.4" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "jemalloc-sys", - "libc", + "typenum", + "version_check", ] [[package]] -name = "jobserver" -version = "0.1.27" +name = "getrandom" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ + "cfg-if", + "js-sys", "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] -name = "js-sys" -version = "0.3.66" +name = "getrandom" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" dependencies = [ - "wasm-bindgen", + "cfg-if", + "libc", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets 0.52.0", ] [[package]] -name = "jsonrpsee" -version = "0.16.3" +name = "gimli" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "367a292944c07385839818bb71c8d76611138e2dedb0677d035b8da21d29c78b" -dependencies = [ - "jsonrpsee-core", - "jsonrpsee-proc-macros", - "jsonrpsee-server", - "jsonrpsee-types", - "tracing", -] +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] -name = "jsonrpsee-core" -version = "0.16.3" +name = "h2" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5dde66c53d6dcdc8caea1874a45632ec0fcf5b437789f1e45766a1512ce803" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ - "anyhow", - "arrayvec", - "async-trait", - "beef", - "futures-channel", + "bytes", + "fnv", + "futures-core", + "futures-sink", "futures-util", - "globset", - "hyper 0.14.27", - "jsonrpsee-types", - "parking_lot 0.12.1", - "rand", - "rustc-hash", - "serde", - "serde_json", - "soketto", - "thiserror", + "http", + "indexmap 2.1.0", + "slab", "tokio", + "tokio-util", "tracing", ] [[package]] -name = "jsonrpsee-proc-macros" -version = "0.16.3" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44e8ab85614a08792b9bff6c8feee23be78c98d0182d4c622c05256ab553892a" -dependencies = [ - "heck 0.4.1", - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] -name = "jsonrpsee-server" -version = "0.16.3" +name = "hashbrown" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4d945a6008c9b03db3354fb3c83ee02d2faa9f2e755ec1dfb69c3551b8f4ba" -dependencies = [ - "futures-channel", - "futures-util", - "http 0.2.11", - "hyper 0.14.27", - "jsonrpsee-core", - "jsonrpsee-types", - "serde", - "serde_json", - "soketto", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tracing", -] +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] -name = "jsonrpsee-types" -version = "0.16.3" +name = "hashbrown" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245ba8e5aa633dd1c1e4fae72bce06e71f42d34c14a2767c6b4d173b57bee5e5" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ - "anyhow", - "beef", - "serde", - "serde_json", - "thiserror", - "tracing", + "allocator-api2", + "equivalent", + "foldhash", ] [[package]] -name = "k256" -version = "0.13.2" +name = "hashlink" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2", + "hashbrown 0.15.2", ] [[package]] -name = "katana-core" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" -dependencies = [ - "alloy-contract", - "alloy-network", - "alloy-primitives", - "alloy-provider", - "alloy-rpc-types", - "alloy-signer", - "alloy-signer-wallet", - "alloy-sol-types", - "alloy-transport", - "anyhow", - "async-trait", - "cairo-lang-casm", - "cairo-lang-starknet", - "cairo-vm", - "convert_case 0.6.0", - "derive_more", - "dojo-metrics", - "flate2", - "futures", - "k256", - "katana-db", - "katana-executor", - "katana-primitives", - "katana-provider", - "katana-tasks", - "lazy_static", - "metrics", - "parking_lot 0.12.1", - "rand", - "reqwest 0.11.22", - "serde", - "serde_json", - "serde_with", - "starknet 0.9.0", - "starknet_api", - "thiserror", - "tokio", - "tracing", - "url", -] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "katana-db" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" -dependencies = [ - "anyhow", - "cairo-vm", - "katana-primitives", - "page_size", - "parking_lot 0.12.1", - "postcard", - "reth-libmdbx", - "roaring", - "serde", - "serde_json", - "starknet_api", - "tempfile", - "thiserror", -] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "katana-executor" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "alloy-primitives", - "blockifier", - "cairo-vm", - "convert_case 0.6.0", - "futures", - "katana-primitives", - "katana-provider", - "parking_lot 0.12.1", - "serde_json", - "starknet 0.9.0", - "starknet_api", - "thiserror", - "tracing", + "hmac", ] [[package]] -name = "katana-primitives" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "alloy-primitives", - "anyhow", - "base64 0.21.5", - "cairo-lang-sierra", - "cairo-lang-starknet", - "cairo-lang-starknet-classes", - "cairo-vm", - "derive_more", - "flate2", - "lazy_static", - "rand", - "rayon", - "serde", - "serde_json", - "serde_with", - "starknet 0.9.0", - "starknet-crypto 0.6.2", - "starknet_api", - "strum 0.25.0", - "strum_macros 0.25.3", - "thiserror", + "digest", ] [[package]] -name = "katana-provider" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "anyhow", - "auto_impl", - "futures", - "katana-db", - "katana-primitives", - "parking_lot 0.12.1", - "starknet 0.9.0", - "thiserror", - "tokio", - "tracing", + "windows-sys 0.52.0", ] [[package]] -name = "katana-rpc" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ - "anyhow", - "base64 0.13.1", - "dojo-metrics", - "flate2", - "futures", - "hex", - "hyper 0.14.27", - "jsonrpsee", - "katana-core", - "katana-executor", - "katana-primitives", - "katana-provider", - "katana-rpc-api", - "katana-rpc-types", - "katana-rpc-types-builder", - "katana-tasks", - "metrics", - "serde", - "serde_json", - "serde_with", - "starknet 0.9.0", - "starknet_api", - "thiserror", - "tokio", - "tower", - "tower-http", - "tracing", + "bytes", + "fnv", + "itoa", ] [[package]] -name = "katana-rpc-api" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "jsonrpsee", - "katana-core", - "katana-primitives", - "katana-rpc-types", - "starknet 0.9.0", + "bytes", + "http", + "pin-project-lite", ] [[package]] -name = "katana-rpc-types" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" -dependencies = [ - "alloy-primitives", - "anyhow", - "derive_more", - "futures", - "jsonrpsee", - "katana-core", - "katana-executor", - "katana-primitives", - "katana-provider", - "serde", - "serde_json", - "serde_with", - "starknet 0.9.0", - "thiserror", -] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] -name = "katana-rpc-types-builder" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" -dependencies = [ - "anyhow", - "katana-executor", - "katana-primitives", - "katana-provider", - "katana-rpc-types", - "starknet 0.9.0", -] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] -name = "katana-tasks" -version = "0.7.0-alpha.1" -source = "git+https://github.com/ArkProjectNFTs/dojo?tag=v0.7.0.6-solis#f6705a463212b2194b5518a04a6e4280b3e40b24" +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ - "futures", - "rayon", - "thiserror", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", "tokio", + "tower-service", + "tracing", + "want", ] [[package]] -name = "keccak" -version = "0.1.4" +name = "hyper-rustls" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ - "cpufeatures", + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", ] [[package]] -name = "keccak-asm" -version = "0.1.1" +name = "hyper-tls" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47a3633291834c4fbebf8673acbc1b04ec9d151418ff9b8e26dcd79129928758" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "digest 0.10.7", - "sha3-asm", + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", ] [[package]] -name = "lalrpop" -version = "0.20.0" +name = "iana-time-zone" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ - "ascii-canvas", - "bit-set", - "diff", - "ena", - "is-terminal", - "itertools 0.10.5", - "lalrpop-util", - "petgraph", - "pico-args", - "regex", - "regex-syntax 0.7.5", - "string_cache", - "term", - "tiny-keccak", - "unicode-xid", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", ] [[package]] -name = "lalrpop-util" -version = "0.20.0" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "regex", + "cc", ] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin 0.5.2", -] +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "lazycell" -version = "1.3.0" +name = "idna" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] [[package]] -name = "libc" -version = "0.2.151" +name = "impl-codec" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] [[package]] -name = "libloading" -version = "0.7.4" +name = "impl-rlp" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" dependencies = [ - "cfg-if", - "winapi", + "rlp", ] [[package]] -name = "libm" -version = "0.2.8" +name = "impl-serde" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] [[package]] -name = "libmimalloc-sys" -version = "0.1.35" +name = "impl-trait-for-tuples" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3979b5c37ece694f1f5e51e7ecc871fdb0f517ed04ee45f88d15d6d553cb9664" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "cc", - "libc", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "libproc" -version = "0.14.2" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229004ebba9d1d5caf41623f1523b6d52abb47d9f6ab87f7e6fc992e3b854aef" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "bindgen", - "errno", - "libc", + "autocfg", + "hashbrown 0.12.3", + "serde", ] [[package]] -name = "libredox" -version = "0.0.1" +name = "indexmap" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ - "bitflags 2.4.1", - "libc", - "redox_syscall 0.4.1", + "equivalent", + "hashbrown 0.14.3", + "serde", ] [[package]] -name = "libsqlite3-sys" -version = "0.27.0" +name = "inout" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "cc", - "pkg-config", - "vcpkg", + "generic-array", ] [[package]] -name = "linux-raw-sys" -version = "0.4.12" +name = "ipnet" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] -name = "lock_api" -version = "0.4.11" +name = "is-terminal" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "autocfg", - "scopeguard", + "hermit-abi", + "rustix 0.38.28", + "windows-sys 0.48.0", ] [[package]] -name = "log" -version = "0.4.20" +name = "is_terminal_polyfill" +version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" [[package]] -name = "lru" -version = "0.7.8" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ - "hashbrown 0.12.3", + "either", ] [[package]] -name = "lru" -version = "0.12.3" +name = "itoa" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" -dependencies = [ - "hashbrown 0.14.3", -] +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] -name = "mach2" -version = "0.4.1" +name = "js-sys" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ - "libc", + "wasm-bindgen", ] [[package]] -name = "matchers" -version = "0.1.0" +name = "keccak" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ - "regex-automata 0.1.10", + "cpufeatures", ] [[package]] -name = "matrixmultiply" -version = "0.2.4" +name = "lambdaworks-crypto" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916806ba0031cd542105d916a97c8572e1fa6dd79c9c51e7eb43a09ec2dd84c1" +checksum = "bbc2a4da0d9e52ccfe6306801a112e81a8fc0c76aa3e4449fefeda7fef72bb34" dependencies = [ - "rawpointer", + "lambdaworks-math", + "serde", + "sha2", + "sha3", ] [[package]] -name = "md-5" -version = "0.10.6" +name = "lambdaworks-math" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +checksum = "d1bd2632acbd9957afc5aeec07ad39f078ae38656654043bf16e046fa2730e23" dependencies = [ - "cfg-if", - "digest 0.10.7", + "serde", + "serde_json", ] [[package]] -name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" +name = "lazy_static" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "autocfg", + "spin 0.5.2", ] [[package]] -name = "metrics" -version = "0.21.1" +name = "libc" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" -dependencies = [ - "ahash 0.8.6", - "metrics-macros", - "portable-atomic", -] +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] -name = "metrics-exporter-prometheus" -version = "0.12.2" +name = "libm" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" -dependencies = [ - "base64 0.21.5", - "hyper 0.14.27", - "indexmap 1.9.3", - "ipnet", - "metrics", - "metrics-util", - "quanta", - "thiserror", - "tokio", - "tracing", -] +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] -name = "metrics-macros" -version = "0.7.0" +name = "libsqlite3-sys" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.64", + "cc", + "pkg-config", + "vcpkg", ] [[package]] -name = "metrics-process" -version = "1.0.14" +name = "linux-raw-sys" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aa2a67e2580fbeba4d5a96e659945981e700a383b4cea1432e0cfc18f58c5da" -dependencies = [ - "libproc", - "mach2", - "metrics", - "once_cell", - "procfs", - "rlimit", - "windows", -] +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] -name = "metrics-util" -version = "0.15.1" +name = "linux-raw-sys" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e" -dependencies = [ - "aho-corasick", - "crossbeam-epoch", - "crossbeam-utils", - "hashbrown 0.13.1", - "indexmap 1.9.3", - "metrics", - "num_cpus", - "ordered-float", - "quanta", - "radix_trie", - "sketches-ddsketch", -] +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] -name = "mimalloc" -version = "0.1.39" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa01922b5ea280a911e323e4d2fd24b7fe5cc4042e0d2cda3c40775cdc4bdc9c" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "libmimalloc-sys", + "autocfg", + "scopeguard", ] [[package]] -name = "mime" -version = "0.3.17" +name = "log" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] -name = "mime_guess" -version = "2.0.4" +name = "matchers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "mime", - "unicase", + "regex-automata 0.1.10", ] [[package]] -name = "minilp" -version = "0.2.2" +name = "md-5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a7750a9e5076c660b7bec5e6457b4dbff402b9863c8d112891434e18fd5385" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "log", - "sprs", + "cfg-if", + "digest", ] [[package]] -name = "minimal-lexical" -version = "0.2.1" +name = "memchr" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" @@ -4177,7 +1667,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -4205,7 +1695,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.100", ] [[package]] @@ -4226,55 +1716,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "ndarray" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac06db03ec2f46ee0ecdca1a1c34a99c0d188a0d83439b84bf0cb4b386e4ab09" -dependencies = [ - "matrixmultiply", - "num-complex", - "num-integer", - "num-traits 0.2.17", - "rawpointer", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec", -] - -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.4.1", - "cfg-if", - "libc", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -4293,9 +1734,7 @@ checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", - "num-traits 0.2.17", - "rand", - "serde", + "num-traits", ] [[package]] @@ -4309,21 +1748,17 @@ dependencies = [ "libm", "num-integer", "num-iter", - "num-traits 0.2.17", + "num-traits", "rand", "smallvec", "zeroize", ] [[package]] -name = "num-complex" -version = "0.2.4" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" -dependencies = [ - "autocfg", - "num-traits 0.2.17", -] +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-integer" @@ -4332,7 +1767,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", - "num-traits 0.2.17", + "num-traits", ] [[package]] @@ -4343,50 +1778,14 @@ checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ "autocfg", "num-integer", - "num-traits 0.2.17", -] - -[[package]] -name = "num-modular" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits 0.2.17", -] - -[[package]] -name = "num-prime" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4e3bc495f6e95bc15a6c0c55ac00421504a5a43d09e3cc455d1fea7015581d" -dependencies = [ - "bitvec", - "either", - "lru 0.7.8", - "num-bigint", - "num-integer", - "num-modular", - "num-traits 0.2.17", - "rand", + "num-traits", ] [[package]] name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -dependencies = [ - "num-traits 0.2.17", -] - -[[package]] -name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -4417,18 +1816,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "openssl" version = "0.10.61" @@ -4452,7 +1839,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.100", ] [[package]] @@ -4463,271 +1850,126 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.2.1+3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" -dependencies = [ - "cc", -] - -[[package]] -name = "openssl-sys" -version = "0.9.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" -dependencies = [ - "cc", - "libc", - "openssl-src", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "ordered-float" -version = "3.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" -dependencies = [ - "num-traits 0.2.17", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "page_size" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" -dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" -dependencies = [ - "proc-macro-crate 2.0.0", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.9", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.4.1", - "smallvec", - "windows-targets 0.48.5", -] - -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "path-clean" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.10" +version = "300.2.1+3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" dependencies = [ - "memchr", - "thiserror", - "ucd-trie", + "cc", ] [[package]] -name = "petgraph" -version = "0.6.4" +name = "openssl-sys" +version = "0.9.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" dependencies = [ - "fixedbitset", - "indexmap 2.1.0", + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", ] [[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +name = "orderbook" +version = "0.1.0" dependencies = [ - "phf_macros", - "phf_shared 0.11.2", + "cainome", + "num-bigint", + "starknet 0.12.0", ] [[package]] -name = "phf_generator" -version = "0.11.2" +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" dependencies = [ - "phf_shared 0.11.2", - "rand", + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", ] [[package]] -name = "phf_macros" -version = "0.11.2" +name = "parity-scale-codec-derive" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ - "phf_generator", - "phf_shared 0.11.2", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.64", + "syn 1.0.109", ] [[package]] -name = "phf_shared" -version = "0.10.0" +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "siphasher", + "lock_api", + "parking_lot_core", ] [[package]] -name = "phf_shared" -version = "0.11.2" +name = "parking_lot_core" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ - "siphasher", + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", ] [[package]] -name = "pico-args" -version = "0.5.0" +name = "paste" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] -name = "pin-project" -version = "1.1.3" +name = "pbkdf2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "pin-project-internal", + "digest", ] [[package]] -name = "pin-project-internal" -version = "1.1.3" +name = "pem-rfc7468" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.64", + "base64ct", ] +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -4784,29 +2026,12 @@ dependencies = [ "serde_json", "sqlx", "starknet 0.10.0", - "thiserror", + "thiserror 1.0.51", "tokio", "tracing", "version-compare", ] -[[package]] -name = "portable-atomic" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" - -[[package]] -name = "postcard" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" -dependencies = [ - "cobs", - "embedded-io", - "serde", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -4819,12 +2044,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "predicates" version = "3.1.0" @@ -4851,6 +2070,16 @@ dependencies = [ "termtree", ] +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn 2.0.100", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -4864,23 +2093,13 @@ dependencies = [ "uint", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_edit 0.20.7", + "toml_edit", ] [[package]] @@ -4909,78 +2128,13 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] -[[package]] -name = "procfs" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "731e0d9356b0c25f16f33b5be79b1c57b562f141ebfcdb0ad8ac2c13a24293b4" -dependencies = [ - "bitflags 2.4.1", - "hex", - "lazy_static", - "procfs-core", - "rustix", -] - -[[package]] -name = "procfs-core" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3554923a69f4ce04c4a754260c338f505ce22642d3830e049a399fc2059a29" -dependencies = [ - "bitflags 2.4.1", - "hex", -] - -[[package]] -name = "proptest" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" -dependencies = [ - "bit-set", - "bit-vec", - "bitflags 2.4.1", - "lazy_static", - "num-traits 0.2.17", - "rand", - "rand_chacha", - "rand_xorshift", - "regex-syntax 0.8.2", - "rusty-fork", - "tempfile", - "unarray", -] - -[[package]] -name = "quanta" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" -dependencies = [ - "crossbeam-utils", - "libc", - "mach2", - "once_cell", - "raw-cpuid", - "wasi", - "web-sys", - "winapi", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quote" version = "1.0.36" @@ -4996,16 +2150,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - [[package]] name = "rand" version = "0.8.5" @@ -5033,60 +2177,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core", -] - -[[package]] -name = "raw-cpuid" -version = "10.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - -[[package]] -name = "rayon" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", + "getrandom 0.2.11", ] [[package]] @@ -5098,17 +2189,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_users" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - [[package]] name = "regex" version = "1.10.2" @@ -5147,24 +2227,12 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - [[package]] name = "regex-syntax" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "relative-path" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" - [[package]] name = "reqwest" version = "0.11.22" @@ -5177,9 +2245,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.11", - "http-body 0.4.6", - "hyper 0.14.27", + "http", + "http-body", + "hyper", "hyper-rustls", "hyper-tls", "ipnet", @@ -5197,87 +2265,15 @@ dependencies = [ "serde_urlencoded", "system-configuration", "tokio", - "tokio-native-tls", - "tokio-rustls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg 0.50.0", -] - -[[package]] -name = "reqwest" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-core", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "http-body-util", - "hyper 1.3.1", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg 0.52.0", -] - -[[package]] -name = "reth-libmdbx" -version = "0.1.0-alpha.13" -source = "git+https://github.com/paradigmxyz/reth.git?rev=b34b0d3#b34b0d3c8de2598b2976f7ee2fc1a166c50b1b94" -dependencies = [ - "bitflags 2.4.1", - "byteorder", - "derive_more", - "indexmap 2.1.0", - "libc", - "parking_lot 0.12.1", - "reth-mdbx-sys", - "thiserror", -] - -[[package]] -name = "reth-mdbx-sys" -version = "0.1.0-alpha.13" -source = "git+https://github.com/paradigmxyz/reth.git?rev=b34b0d3#b34b0d3c8de2598b2976f7ee2fc1a166c50b1b94" -dependencies = [ - "bindgen", - "cc", - "libc", -] - -[[package]] -name = "reth-metrics-derive" -version = "0.2.0-beta.4" -source = "git+https://github.com/paradigmxyz/reth.git?tag=v0.2.0-beta.4#c04dbe6e9bd05be5da3a5d541adbf76166c14a08" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "regex", - "syn 2.0.64", + "tokio-native-tls", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", ] [[package]] @@ -5297,22 +2293,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", - "getrandom", + "getrandom 0.2.11", "libc", "spin 0.9.8", "untrusted", "windows-sys 0.48.0", ] -[[package]] -name = "rlimit" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3560f70f30a0f16d11d01ed078a07740fe6b489667abc7c7b029155d9f21c3d8" -dependencies = [ - "libc", -] - [[package]] name = "rlp" version = "0.5.2" @@ -5323,17 +2310,6 @@ dependencies = [ "rustc-hex", ] -[[package]] -name = "roaring" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b26f4c25a604fcb3a1bcd96dd6ba37c93840de95de8198d94c0d571a74a804d1" -dependencies = [ - "bytemuck", - "byteorder", - "serde", -] - [[package]] name = "rsa" version = "0.9.6" @@ -5341,10 +2317,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" dependencies = [ "const-oid", - "digest 0.10.7", + "digest", "num-bigint-dig", "num-integer", - "num-traits 0.2.17", + "num-traits", "pkcs1", "pkcs8", "rand_core", @@ -5354,74 +2330,12 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rstest" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de1bb486a691878cd320c2f0d319ba91eeaa2e894066d8b5f8f117c000e9d962" -dependencies = [ - "futures", - "futures-timer", - "rstest_macros", - "rustc_version 0.4.0", -] - -[[package]] -name = "rstest_macros" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290ca1a1c8ca7edb7c3283bd44dc35dd54fdec6253a3912e201ba1072018fca8" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "rustc_version 0.4.0", - "syn 1.0.109", - "unicode-ident", -] - -[[package]] -name = "ruint" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f308135fef9fc398342da5472ce7c484529df23743fb7c734e0f3d472971e62" -dependencies = [ - "alloy-rlp", - "ark-ff 0.3.0", - "ark-ff 0.4.2", - "bytes", - "fastrlp", - "num-bigint", - "num-traits 0.2.17", - "parity-scale-codec", - "primitive-types", - "proptest", - "rand", - "rlp", - "ruint-macro", - "serde", - "valuable", - "zeroize", -] - -[[package]] -name = "ruint-macro" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343" - [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hex" version = "2.1.0" @@ -5430,32 +2344,36 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustc_version" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 0.11.0", + "semver", ] [[package]] -name = "rustc_version" -version = "0.4.0" +name = "rustix" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ - "semver 1.0.20", + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", ] [[package]] name = "rustix" -version = "0.38.28" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.9.3", "windows-sys 0.52.0", ] @@ -5490,59 +2408,12 @@ dependencies = [ "untrusted", ] -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - -[[package]] -name = "rusty-fork" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] - [[package]] name = "ryu" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" -[[package]] -name = "salsa" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b84d9f96071f3f3be0dc818eae3327625d8ebc95b58da37d6850724f31d3403" -dependencies = [ - "crossbeam-utils", - "indexmap 1.9.3", - "lock_api", - "log", - "oorandom", - "parking_lot 0.11.2", - "rustc-hash", - "salsa-macros", - "smallvec", -] - -[[package]] -name = "salsa-macros" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3904a4ba0a9d0211816177fd34b04c7095443f8cdacd11175064fe541c8fe2" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "salsa20" version = "0.10.2" @@ -5569,7 +2440,7 @@ dependencies = [ "serde_json", "sqlx", "starknet 0.10.0", - "thiserror", + "thiserror 1.0.51", "tokio", "tracing", "version-compare", @@ -5584,31 +2455,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "schemars" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" -dependencies = [ - "dyn-clone", - "indexmap 1.9.3", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 1.0.109", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -5637,20 +2483,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - [[package]] name = "security-framework" version = "2.9.2" @@ -5674,30 +2506,12 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.202" @@ -5715,18 +2529,7 @@ checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", -] - -[[package]] -name = "serde_derive_internals" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "syn 2.0.100", ] [[package]] @@ -5751,15 +2554,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -5784,7 +2578,25 @@ dependencies = [ "indexmap 1.9.3", "serde", "serde_json", - "serde_with_macros", + "serde_with_macros 2.3.3", + "time", +] + +[[package]] +name = "serde_with" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.1.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros 3.9.0", "time", ] @@ -5794,23 +2606,22 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling 0.20.3", + "darling", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.100", ] [[package]] -name = "sha-1" -version = "0.9.8" +name = "serde_with_macros" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "darling", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -5821,7 +2632,7 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -5832,7 +2643,7 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -5841,20 +2652,10 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.7", + "digest", "keccak", ] -[[package]] -name = "sha3-asm" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9b57fd861253bff08bb1919e995f90ba8f4889de2726091c8876f3a4e823b40" -dependencies = [ - "cc", - "cfg-if", -] - [[package]] name = "sharded-slab" version = "0.1.7" @@ -5864,20 +2665,11 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shellexpand" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" -dependencies = [ - "dirs", -] - [[package]] name = "shlex" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" @@ -5894,22 +2686,10 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest 0.10.7", + "digest", "rand_core", ] -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "sketches-ddsketch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" - [[package]] name = "slab" version = "0.4.9" @@ -5924,12 +2704,6 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "smol_str" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" dependencies = [ "serde", ] @@ -5954,53 +2728,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "soketto" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" -dependencies = [ - "base64 0.13.1", - "bytes", - "futures", - "http 0.2.11", - "httparse", - "log", - "rand", - "sha-1", -] - -[[package]] -name = "solis" -version = "0.7.0-alpha-1" -dependencies = [ - "alloy-primitives", - "anyhow", - "assert_matches", - "async-trait", - "cainome 0.2.3", - "cfg-if", - "clap", - "clap_complete", - "common", - "console", - "dojo-metrics", - "dotenv", - "katana-core", - "katana-executor", - "katana-primitives", - "katana-rpc", - "katana-rpc-api", - "serde_json", - "shellexpand", - "starknet 0.9.0", - "starknet_api", - "tokio", - "tracing", - "tracing-subscriber", - "url", -] - [[package]] name = "spin" version = "0.5.2" @@ -6008,51 +2735,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "sprs" -version = "0.7.1" +name = "spin" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec63571489873d4506683915840eeb1bb16b3198ee4894cc6f2fe3013d505e56" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ - "ndarray", - "num-complex", - "num-traits 0.1.43", + "lock_api", ] [[package]] -name = "sqlformat" -version = "0.2.3" +name = "spki" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ - "itertools 0.12.0", - "nom", - "unicode_categories", + "base64ct", + "der", ] [[package]] name = "sqlx" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +checksum = "4410e73b3c0d8442c5f99b425d7a435b5ee0ae4167b3196771dd3f7a01be745f" dependencies = [ "sqlx-core", "sqlx-macros", @@ -6063,38 +2768,31 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +checksum = "6a007b6936676aa9ab40207cde35daab0a04b823be8ae004368c0793b96a61e0" dependencies = [ - "ahash 0.8.6", - "atoi", - "byteorder", "bytes", "crc", "crossbeam-queue", - "dotenvy", "either", "event-listener", - "futures-channel", "futures-core", "futures-intrusive", "futures-io", "futures-util", + "hashbrown 0.15.2", "hashlink", - "hex", "indexmap 2.1.0", "log", "memchr", "once_cell", - "paste", "percent-encoding", "serde", "serde_json", "sha2", "smallvec", - "sqlformat", - "thiserror", + "thiserror 2.0.12", "tokio", "tokio-stream", "tracing", @@ -6103,27 +2801,26 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +checksum = "3112e2ad78643fef903618d78cf0aec1cb3134b019730edb039b69eaf531f310" dependencies = [ "proc-macro2", "quote", "sqlx-core", "sqlx-macros-core", - "syn 1.0.109", + "syn 2.0.100", ] [[package]] name = "sqlx-macros-core" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +checksum = "4e9f90acc5ab146a99bf5061a7eb4976b573f560bc898ef3bf8435448dd5e7ad" dependencies = [ - "atomic-write-file", "dotenvy", "either", - "heck 0.4.1", + "heck", "hex", "once_cell", "proc-macro2", @@ -6135,7 +2832,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 1.0.109", + "syn 2.0.100", "tempfile", "tokio", "url", @@ -6143,17 +2840,17 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +checksum = "4560278f0e00ce64938540546f59f590d60beee33fffbd3b9cd47851e5fff233" dependencies = [ "atoi", - "base64 0.21.5", + "base64 0.22.1", "bitflags 2.4.1", "byteorder", "bytes", "crc", - "digest 0.10.7", + "digest", "dotenvy", "either", "futures-channel", @@ -6178,19 +2875,19 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror", + "thiserror 2.0.12", "tracing", "whoami", ] [[package]] name = "sqlx-postgres" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +checksum = "c5b98a57f363ed6764d5b3a12bfedf62f07aa16e1856a7ddc2a0bb190a959613" dependencies = [ "atoi", - "base64 0.21.5", + "base64 0.22.1", "bitflags 2.4.1", "byteorder", "crc", @@ -6198,7 +2895,6 @@ dependencies = [ "etcetera", "futures-channel", "futures-core", - "futures-io", "futures-util", "hex", "hkdf", @@ -6212,21 +2908,20 @@ dependencies = [ "rand", "serde", "serde_json", - "sha1", "sha2", "smallvec", "sqlx-core", "stringprep", - "thiserror", + "thiserror 2.0.12", "tracing", "whoami", ] [[package]] name = "sqlx-sqlite" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +checksum = "f85ca71d3a5b24e64e1d08dd8fe36c6c95c339a896cc33068148906784620540" dependencies = [ "atoi", "flume", @@ -6239,10 +2934,10 @@ dependencies = [ "log", "percent-encoding", "serde", + "serde_urlencoded", "sqlx-core", "tracing", "url", - "urlencoding", ] [[package]] @@ -6256,43 +2951,11 @@ dependencies = [ "starknet-core 0.7.2", "starknet-crypto 0.6.2", "starknet-ff", - "starknet-macros", + "starknet-macros 0.1.7", "starknet-providers 0.7.0", "starknet-signers 0.5.0", ] -[[package]] -name = "starknet" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb139c5e6f6c6da627080e33cc00b3fc1c9733403034ca1ee9c42a95c337c7f" -dependencies = [ - "starknet-accounts 0.7.0", - "starknet-contract 0.7.0", - "starknet-core 0.8.0", - "starknet-crypto 0.6.2", - "starknet-ff", - "starknet-macros", - "starknet-providers 0.8.0", - "starknet-signers 0.6.0", -] - -[[package]] -name = "starknet" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f8002bf3d750dd2c0434aca8b5e88e2438cd6c452f4c18f34d0a8a9f42cb1a" -dependencies = [ - "starknet-accounts 0.8.0", - "starknet-contract 0.8.0", - "starknet-core 0.9.0", - "starknet-crypto 0.6.2", - "starknet-ff", - "starknet-macros", - "starknet-providers 0.9.0", - "starknet-signers 0.7.0", -] - [[package]] name = "starknet" version = "0.10.0" @@ -6304,65 +2967,67 @@ dependencies = [ "starknet-core 0.10.0", "starknet-crypto 0.6.2", "starknet-ff", - "starknet-macros", + "starknet-macros 0.1.7", "starknet-providers 0.10.0", "starknet-signers 0.8.0", ] [[package]] -name = "starknet-accounts" -version = "0.6.1" +name = "starknet" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7062b020f65d9da7f9dd9f1d97bfb644e881cda8ddb999799a799e6f2e408dd" +checksum = "6f0c9ac3809cc7630784e8c8565fa3013af819d83c97aa2720d566016d439011" dependencies = [ - "async-trait", - "auto_impl", - "starknet-core 0.7.2", - "starknet-providers 0.7.0", - "starknet-signers 0.5.0", - "thiserror", + "starknet-accounts 0.11.0", + "starknet-contract 0.11.0", + "starknet-core 0.12.0", + "starknet-crypto 0.7.2", + "starknet-macros 0.2.1", + "starknet-providers 0.12.0", + "starknet-signers 0.10.0", ] [[package]] name = "starknet-accounts" -version = "0.7.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3743932c80ad2a5868c2dd4ef729de4e12060c88e73e4bb678a5f8e51b105e53" +checksum = "c7062b020f65d9da7f9dd9f1d97bfb644e881cda8ddb999799a799e6f2e408dd" dependencies = [ "async-trait", "auto_impl", - "starknet-core 0.8.0", - "starknet-providers 0.8.0", - "starknet-signers 0.6.0", - "thiserror", + "starknet-core 0.7.2", + "starknet-providers 0.7.0", + "starknet-signers 0.5.0", + "thiserror 1.0.51", ] [[package]] name = "starknet-accounts" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e39a5807a735343493781dd5e640c4af838de470b0a73f420bed642fdc2ff1" +checksum = "2095d7584608ae1707bd1cf2889368ab3734d9f54e4fcef4765cba1f3b3f7618" dependencies = [ "async-trait", "auto_impl", - "starknet-core 0.9.0", - "starknet-providers 0.9.0", - "starknet-signers 0.7.0", - "thiserror", + "starknet-core 0.10.0", + "starknet-providers 0.10.0", + "starknet-signers 0.8.0", + "thiserror 1.0.51", ] [[package]] name = "starknet-accounts" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2095d7584608ae1707bd1cf2889368ab3734d9f54e4fcef4765cba1f3b3f7618" +checksum = "0ee27ded58ade61da410fccafd57ed5429b0e79a9d62a4ae8b65818cb9d6f400" dependencies = [ "async-trait", "auto_impl", - "starknet-core 0.10.0", - "starknet-providers 0.10.0", - "starknet-signers 0.8.0", - "thiserror", + "starknet-core 0.12.0", + "starknet-crypto 0.7.2", + "starknet-providers 0.12.0", + "starknet-signers 0.10.0", + "thiserror 1.0.51", ] [[package]] @@ -6373,41 +3038,11 @@ checksum = "d858efc93d85de95065a5732cb3e94d0c746674964c0859aab442ffbb9de76b4" dependencies = [ "serde", "serde_json", - "serde_with", + "serde_with 2.3.3", "starknet-accounts 0.6.1", "starknet-core 0.7.2", "starknet-providers 0.7.0", - "thiserror", -] - -[[package]] -name = "starknet-contract" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e55aac528c5376e1626d5a8d4daaf280bfd08f909dadc729e5b009203d6ec21" -dependencies = [ - "serde", - "serde_json", - "serde_with", - "starknet-accounts 0.7.0", - "starknet-core 0.8.0", - "starknet-providers 0.8.0", - "thiserror", -] - -[[package]] -name = "starknet-contract" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4996991356cd0e9499c663680eba7e77de4109e4995f652c1608899a65c09ee" -dependencies = [ - "serde", - "serde_json", - "serde_with", - "starknet-accounts 0.8.0", - "starknet-core 0.9.0", - "starknet-providers 0.9.0", - "thiserror", + "thiserror 1.0.51", ] [[package]] @@ -6418,36 +3053,33 @@ checksum = "cb3b73d437b4d62241612d13fce612602de6684c149cccf696e76a20757e2156" dependencies = [ "serde", "serde_json", - "serde_with", + "serde_with 2.3.3", "starknet-accounts 0.9.0", "starknet-core 0.10.0", "starknet-providers 0.10.0", - "thiserror", + "thiserror 1.0.51", ] [[package]] -name = "starknet-core" -version = "0.7.2" +name = "starknet-contract" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1683ca7c63f0642310eddedb7d35056d8306084dff323d440711065c63ed87" +checksum = "bd6ee5762d24c4f06ab7e9406550925df406712e73719bd2de905c879c674a87" dependencies = [ - "base64 0.21.5", - "flate2", - "hex", "serde", "serde_json", - "serde_json_pythonic", - "serde_with", - "sha3", - "starknet-crypto 0.6.2", - "starknet-ff", + "serde_with 3.9.0", + "starknet-accounts 0.11.0", + "starknet-core 0.12.0", + "starknet-providers 0.12.0", + "thiserror 1.0.51", ] [[package]] name = "starknet-core" -version = "0.8.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50e281d4fdb97988a3d5c7b7cae22b9d67bb2ef9be2cfafc17a1e35542cb53" +checksum = "7f1683ca7c63f0642310eddedb7d35056d8306084dff323d440711065c63ed87" dependencies = [ "base64 0.21.5", "flate2", @@ -6455,7 +3087,7 @@ dependencies = [ "serde", "serde_json", "serde_json_pythonic", - "serde_with", + "serde_with 2.3.3", "sha3", "starknet-crypto 0.6.2", "starknet-ff", @@ -6463,9 +3095,9 @@ dependencies = [ [[package]] name = "starknet-core" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b15034c07557615f6bea248cb2ac91a103f56792c515319025a5edc4de2a60e" +checksum = "5ed286d637e34fb8ae1cd2f9615120ec8ff38d1cffd311ed7fdd497cdd2bd01f" dependencies = [ "base64 0.21.5", "flate2", @@ -6473,7 +3105,7 @@ dependencies = [ "serde", "serde_json", "serde_json_pythonic", - "serde_with", + "serde_with 2.3.3", "sha3", "starknet-crypto 0.6.2", "starknet-ff", @@ -6481,59 +3113,59 @@ dependencies = [ [[package]] name = "starknet-core" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ed286d637e34fb8ae1cd2f9615120ec8ff38d1cffd311ed7fdd497cdd2bd01f" +checksum = "2538240cbe6663c673fe77465f294da707080f39678dd7066761554899e46100" dependencies = [ "base64 0.21.5", + "crypto-bigint", "flate2", "hex", "serde", "serde_json", "serde_json_pythonic", - "serde_with", + "serde_with 3.9.0", "sha3", - "starknet-crypto 0.6.2", - "starknet-ff", + "starknet-crypto 0.7.2", + "starknet-types-core", ] [[package]] name = "starknet-crypto" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f2175b0b3fc24ff2ec6dc07f5a720498994effca7e78b11a6e1c1bd02cad52" +checksum = "2e2c30c01e8eb0fc913c4ee3cf676389fffc1d1182bfe5bb9670e4e72e968064" dependencies = [ "crypto-bigint", "hex", "hmac", "num-bigint", "num-integer", - "num-traits 0.2.17", + "num-traits", "rfc6979", "sha2", "starknet-crypto-codegen", - "starknet-curve 0.3.0", + "starknet-curve 0.4.2", "starknet-ff", "zeroize", ] [[package]] name = "starknet-crypto" -version = "0.6.2" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2c30c01e8eb0fc913c4ee3cf676389fffc1d1182bfe5bb9670e4e72e968064" +checksum = "60a5064173a8e8d2675e67744fd07f310de44573924b6b7af225a6bdd8102913" dependencies = [ "crypto-bigint", "hex", "hmac", "num-bigint", "num-integer", - "num-traits 0.2.17", + "num-traits", "rfc6979", "sha2", - "starknet-crypto-codegen", - "starknet-curve 0.4.2", - "starknet-ff", + "starknet-curve 0.5.1", + "starknet-types-core", "zeroize", ] @@ -6545,25 +3177,25 @@ checksum = "bbc159a1934c7be9761c237333a57febe060ace2bc9e3b337a59a37af206d19f" dependencies = [ "starknet-curve 0.4.2", "starknet-ff", - "syn 2.0.64", + "syn 2.0.100", ] [[package]] name = "starknet-curve" -version = "0.3.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252610baff59e4c4332ce3569f7469c5d3f9b415a2240d698fb238b2b4fc0942" +checksum = "d1c383518bb312751e4be80f53e8644034aa99a0afb29d7ac41b89a997db875b" dependencies = [ "starknet-ff", ] [[package]] name = "starknet-curve" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1c383518bb312751e4be80f53e8644034aa99a0afb29d7ac41b89a997db875b" +checksum = "bcde6bd74269b8161948190ace6cf069ef20ac6e79cd2ba09b320efa7500b6de" dependencies = [ - "starknet-ff", + "starknet-types-core", ] [[package]] @@ -6572,10 +3204,10 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abf1b44ec5b18d87c1ae5f54590ca9d0699ef4dd5b2ffa66fc97f24613ec585" dependencies = [ - "ark-ff 0.4.2", + "ark-ff", "bigdecimal", "crypto-bigint", - "getrandom", + "getrandom 0.2.11", "hex", "num-bigint", "serde", @@ -6588,86 +3220,77 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95d549d3078bdbe775d0deaa8ddb57a19942989ce7c1f2dfd60beeb322bb4945" dependencies = [ "starknet-core 0.10.0", - "syn 2.0.64", + "syn 2.0.100", ] [[package]] -name = "starknet-providers" -version = "0.7.0" +name = "starknet-macros" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52072c2d258bf692affeccd602613d5f6c61a6ffc84da8f191ab4a1b0a5e24d1" +checksum = "8986a940af916fc0a034f4e42c6ba76d94f1e97216d75447693dfd7aefaf3ef2" dependencies = [ - "async-trait", - "auto_impl", - "ethereum-types", - "flate2", - "log", - "reqwest 0.11.22", - "serde", - "serde_json", - "serde_with", - "starknet-core 0.7.2", - "thiserror", - "url", + "starknet-core 0.12.0", + "syn 2.0.100", ] [[package]] name = "starknet-providers" -version = "0.8.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b08084f36ff7f11743ec71f33f0b11d439cbe0524058def299eb47de1ef1c28" +checksum = "52072c2d258bf692affeccd602613d5f6c61a6ffc84da8f191ab4a1b0a5e24d1" dependencies = [ "async-trait", "auto_impl", "ethereum-types", "flate2", "log", - "reqwest 0.11.22", + "reqwest", "serde", "serde_json", - "serde_with", - "starknet-core 0.8.0", - "thiserror", + "serde_with 2.3.3", + "starknet-core 0.7.2", + "thiserror 1.0.51", "url", ] [[package]] name = "starknet-providers" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4bd1c262936543d6d14d299f476585e8c9625a4e284d9255b54f1c2e68e64a" +checksum = "b6abf40ffcbe3b887b4d5cfc8ab73170c816b4aa78d1d4ad59abd3fb3b0f53cd" dependencies = [ "async-trait", "auto_impl", "ethereum-types", "flate2", "log", - "reqwest 0.11.22", + "reqwest", "serde", "serde_json", - "serde_with", - "starknet-core 0.9.0", - "thiserror", + "serde_with 2.3.3", + "starknet-core 0.10.0", + "thiserror 1.0.51", "url", ] [[package]] name = "starknet-providers" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6abf40ffcbe3b887b4d5cfc8ab73170c816b4aa78d1d4ad59abd3fb3b0f53cd" +checksum = "60e8e69ba7a36dea2d28333be82b4011f8784333d3ae5618482b6587c1ffb66c" dependencies = [ "async-trait", "auto_impl", "ethereum-types", "flate2", + "getrandom 0.2.11", "log", - "reqwest 0.11.22", + "reqwest", "serde", "serde_json", - "serde_with", - "starknet-core 0.10.0", - "thiserror", + "serde_with 3.9.0", + "starknet-core 0.12.0", + "thiserror 1.0.51", "url", ] @@ -6684,75 +3307,54 @@ dependencies = [ "rand", "starknet-core 0.7.2", "starknet-crypto 0.6.2", - "thiserror", -] - -[[package]] -name = "starknet-signers" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91919d8f318f0b5bcc4ff5849fbd3fb46adaaa72e0bf204742bab7c822425ff4" -dependencies = [ - "async-trait", - "auto_impl", - "crypto-bigint", - "eth-keystore", - "rand", - "starknet-core 0.8.0", - "starknet-crypto 0.6.2", - "thiserror", + "thiserror 1.0.51", ] [[package]] name = "starknet-signers" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c5eb659e66b56ceafb9025cd601226d8f34d273f1b826cd4053ab6333ff0898" +checksum = "5e9a2bd4fd66090003c3b7f0d76476e5b63cd44f6a49ede2442673f4427d5a40" dependencies = [ "async-trait", "auto_impl", "crypto-bigint", "eth-keystore", "rand", - "starknet-core 0.9.0", + "starknet-core 0.10.0", "starknet-crypto 0.6.2", - "thiserror", + "thiserror 1.0.51", ] [[package]] name = "starknet-signers" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9a2bd4fd66090003c3b7f0d76476e5b63cd44f6a49ede2442673f4427d5a40" +checksum = "70b9e01b61ae51d722e2b100d6ef913c5a2e70d1ea672733d385f7296d6055ef" dependencies = [ "async-trait", "auto_impl", "crypto-bigint", "eth-keystore", + "getrandom 0.2.11", "rand", - "starknet-core 0.10.0", - "starknet-crypto 0.6.2", - "thiserror", + "starknet-core 0.12.0", + "starknet-crypto 0.7.2", + "thiserror 1.0.51", ] [[package]] -name = "starknet_api" -version = "0.10.0" +name = "starknet-types-core" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e6aeb260177f5ca6dde788e844825d8d83782905dbac1b24c0c620743284475" +checksum = "fa1b9e01ccb217ab6d475c5cda05dbb22c30029f7bb52b192a010a00d77a3d74" dependencies = [ - "cairo-lang-starknet-classes", - "derive_more", - "hex", - "indexmap 2.1.0", - "once_cell", - "primitive-types", + "lambdaworks-crypto", + "lambdaworks-math", + "num-bigint", + "num-integer", + "num-traits", "serde", - "serde_json", - "starknet-crypto 0.5.2", - "strum 0.24.1", - "strum_macros 0.24.3", - "thiserror", ] [[package]] @@ -6761,19 +3363,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot 0.12.1", - "phf_shared 0.10.0", - "precomputed-hash", -] - [[package]] name = "stringprep" version = "0.1.4" @@ -6797,44 +3386,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.64", -] - [[package]] name = "subtle" version = "2.5.0" @@ -6854,33 +3405,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.64" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn-solidity" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8db114c44cf843a8bacd37a146e37987a0b823a0e8bc4fdc610c9c72ab397a5" -dependencies = [ - "paste", - "proc-macro2", - "quote", - "syn 2.0.64", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "system-configuration" version = "0.5.1" @@ -6905,31 +3438,20 @@ dependencies = [ [[package]] name = "tap" version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tempfile" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall 0.4.1", - "rustix", - "windows-sys 0.48.0", -] +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "term" -version = "0.7.0" +name = "tempfile" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" dependencies = [ - "dirs-next", - "rustversion", - "winapi", + "fastrand", + "getrandom 0.3.1", + "once_cell", + "rustix 1.0.2", + "windows-sys 0.52.0", ] [[package]] @@ -6953,38 +3475,38 @@ version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.51", ] [[package]] -name = "thiserror-impl" -version = "1.0.51" +name = "thiserror" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.64", + "thiserror-impl 2.0.12", ] [[package]] -name = "thiserror-impl-no-std" -version = "2.0.2" +name = "thiserror-impl" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.100", ] [[package]] -name = "thiserror-no-std" -version = "2.0.2" +name = "thiserror-impl" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ - "thiserror-impl-no-std", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -6997,23 +3519,15 @@ dependencies = [ "once_cell", ] -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - [[package]] name = "time" -version = "0.3.30" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -7028,10 +3542,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -7070,7 +3585,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.5.5", @@ -7086,7 +3601,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.100", ] [[package]] @@ -7118,7 +3633,6 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", - "tokio-util", ] [[package]] @@ -7129,44 +3643,17 @@ checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", - "futures-io", "futures-sink", "pin-project-lite", "tokio", "tracing", ] -[[package]] -name = "toml" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.21.0", -] - [[package]] name = "toml_datetime" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow 0.5.28", -] [[package]] name = "toml_edit" @@ -7176,79 +3663,9 @@ checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ "indexmap 2.1.0", "toml_datetime", - "winnow 0.5.28", -] - -[[package]] -name = "toml_edit" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" -dependencies = [ - "indexmap 2.1.0", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.5.28", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "hdrhistogram", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" -dependencies = [ - "async-compression", - "base64 0.21.5", - "bitflags 2.4.1", - "bytes", - "futures-core", - "futures-util", - "http 0.2.11", - "http-body 0.4.6", - "http-range-header", - "httpdate", - "iri-string", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite", - "tokio", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "uuid 1.6.1", + "winnow", ] -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - [[package]] name = "tower-service" version = "0.3.2" @@ -7275,7 +3692,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.100", ] [[package]] @@ -7353,12 +3770,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - [[package]] name = "uint" version = "0.9.5" @@ -7371,30 +3782,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "unarray" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" - -[[package]] -name = "unescaper" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f0f68e58d297ba8b22b8b5a96a87b863ba6bb46aaf51e19a4b02c5a6dd5b7f" -dependencies = [ - "thiserror", -] - -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.14" @@ -7422,24 +3809,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - [[package]] name = "untrusted" version = "0.9.0" @@ -7455,7 +3824,6 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] [[package]] @@ -7476,19 +3844,10 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom", + "getrandom 0.2.11", "serde", ] -[[package]] -name = "uuid" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" -dependencies = [ - "getrandom", -] - [[package]] name = "valuable" version = "0.1.0" @@ -7513,15 +3872,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - [[package]] name = "want" version = "0.3.1" @@ -7537,6 +3887,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.89" @@ -7558,7 +3917,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.100", "wasm-bindgen-shared", ] @@ -7592,7 +3951,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7656,16 +4015,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" -dependencies = [ - "windows-core 0.52.0", - "windows-targets 0.52.0", -] - [[package]] name = "windows-core" version = "0.51.1" @@ -7675,24 +4024,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -7711,21 +4042,6 @@ dependencies = [ "windows-targets 0.52.0", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -7756,12 +4072,6 @@ dependencies = [ "windows_x86_64_msvc 0.52.0", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -7774,12 +4084,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -7792,12 +4096,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -7810,12 +4108,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -7828,12 +4120,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -7846,12 +4132,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -7864,12 +4144,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -7891,15 +4165,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winnow" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" version = "0.50.0" @@ -7911,13 +4176,12 @@ dependencies = [ ] [[package]] -name = "winreg" -version = "0.52.0" +name = "wit-bindgen-rt" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "bitflags 2.4.1", ] [[package]] @@ -7929,41 +4193,6 @@ dependencies = [ "tap", ] -[[package]] -name = "xshell" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2107fe03e558353b4c71ad7626d58ed82efaf56c54134228608893c77023ad" -dependencies = [ - "xshell-macros", -] - -[[package]] -name = "xshell-macros" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e2c411759b501fb9501aac2b1b2d287a6e93e5bdcf13c25306b23e1b716dd0e" - -[[package]] -name = "zerocopy" -version = "0.7.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.64", -] - [[package]] name = "zeroize" version = "1.7.0" @@ -7981,38 +4210,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", -] - -[[package]] -name = "zstd" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" -dependencies = [ - "zstd-sys", + "syn 2.0.100", ] - -[[package]] -name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" -dependencies = [ - "cc", - "pkg-config", -] - -[[patch.unused]] -name = "blockifier" -version = "0.4.0-rc9.2" -source = "git+https://github.com/dojoengine/blockifier?rev=e6e9c90#e6e9c902ce699269e38aecda49dc50bd11a9bec0" diff --git a/Cargo.toml b/Cargo.toml index a3c29bf67..d0736b3d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,16 +11,15 @@ homepage = "https://arkproject.dev" description = """ ArkProject libraries written in Rust """ -exclude = ["crates/solis"] [workspace] members = [ "crates/ark-metadata", "crates/ark-starknet", "crates/pontos", - "crates/solis", "crates/diri", "crates/sana", + "crates/orderbook", ] [workspace.dependencies] @@ -29,6 +28,8 @@ ark-metadata = { path = "./crates/ark-metadata" } pontos = { path = "./crates/pontos" } sana = { path = "./crates/sana" } diri = { path = "./crates/diri" } +orderbook = { path = "./crates/orderbook" } + async-trait = "0.1.73" starknet = "0.10.0" anyhow = "1.0" @@ -48,29 +49,11 @@ ark-metadata.workspace = true pontos = { path = "./crates/pontos", features = ["sqlxdb"] } sana = { path = "./crates/sana", features = ["sqlxdb"] } diri.workspace = true +orderbook.workspace = true tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } tracing = "0.1" tracing-log = "0.1" -sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio"] } -alloy-primitives = { version = "0.7.1", default-features = false } -alloy-sol-types = { version = "0.7.1", default-features = false } - -# ** SOLIS ** -[patch."https://github.com/starkware-libs/blockifier"] -blockifier = { git = "https://github.com/dojoengine/blockifier", rev = "e6e9c90" } - -[patch.crates-io] -cairo-felt = { git = "https://github.com/dojoengine/cairo-rs.git", rev = "1031381" } -cairo-vm = { git = "https://github.com/dojoengine/cairo-rs.git", rev = "1031381" } - -alloy-contract = { git = "https://github.com/alloy-rs/alloy", rev = "5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" } -alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" } -alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" } -alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" } -alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" } -alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" } -alloy-signer-wallet = { git = "https://github.com/alloy-rs/alloy", rev = "5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" } -alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "5a5f29eb7d92a194bb2c67b1f879e84b2c6716ce" } +sqlx = { version = "0.8.2", features = ["sqlite", "runtime-tokio"] } [dev-dependencies] mockall = "0.12.1" diff --git a/README.md b/README.md index 735176198..b458351ef 100644 --- a/README.md +++ b/README.md @@ -117,9 +117,9 @@ Check out our demo app showcasing a mini marketplace: [ArkProject SDK Demo](http cp .env.example .env ``` -1. **Install the latest Dojo version** (currently 0.0.7-alpha.1) +1. **Install the latest Starknet Devnet version** (currently 0.2.0) - - Follow the guide: https://book.dojoengine.org/getting-started + - Follow the guide: https://0xspaceshard.github.io/starknet-devnet-rs/docs/running/install 2. **Install Packages** @@ -133,10 +133,12 @@ Check out our demo app showcasing a mini marketplace: [ArkProject SDK Demo](http cd contracts && scarb build --workspace ``` -4. **Launch Katana** +4. **Launch Starknet Devnet** + + using the cmd line (or with the method you prefer, like docker) ```bash - katana + starknet-devnet ``` 5. **Deploy Starknet Contracts** @@ -145,25 +147,13 @@ Check out our demo app showcasing a mini marketplace: [ArkProject SDK Demo](http pnpm deploy:starknet:local ``` -6. **Launch Solis** - - ```bash - cargo run -p solis -- --chain-id 0x736f6c6973 --messaging crates/solis/messaging.local.json --disable-fee -p 7777 - ``` - -7. **Deploy Solis Contracts** - - ```bash - pnpm deploy:solis:local - ``` - -8. **Build the Core and React SDKs** +6. **Build the Core and React SDKs** ```bash - pnpm build --filter=core --filter=react + pnpm build ``` -9. **Try Core SDK Examples** +7. **Try Core SDK Examples** ```bash cd examples/core diff --git a/contracts.json b/contracts.json index e154df175..c629dc143 100644 --- a/contracts.json +++ b/contracts.json @@ -1,12 +1,8 @@ { "sepolia": { - "messaging": "0x74f13f1dffb5ad3c051d535ba03514e653b6dcac68e30b2db66a0aa0217c815", - "executor": "0xb86ab357c15c12fb78f9b0a19fa974c730fcbab96f17881827dde871665f0b", - "orderbook": "0x795b605fa3144afd6f11a4499f71b9cf373bcba3f1b2835d51f65ab59392261" + "executor": "0xb86ab357c15c12fb78f9b0a19fa974c730fcbab96f17881827dde871665f0b" }, "mainnet": { - "messaging": "0x57d45cc46de463f7ae63b74ce9b6b6b496a1178b02e7ad04d7c307caa698b7b", - "executor": "0x7b42945bc47001db92fe1b9739d753925263f2f1036c2ae1f87536c916ee6a", - "orderbook": "0x5add3084bb8664eb2a641cf26a28f60588c3ccd63af0632aafefcbb2332c345" + "executor": "0x56ea156367ba964adac5e84d61b89fadf262074c9b272ba415d8b13cb461ab8" } } \ No newline at end of file diff --git a/contracts/.tool-versions b/contracts/.tool-versions index 90faff46b..27f5ea63a 100644 --- a/contracts/.tool-versions +++ b/contracts/.tool-versions @@ -1,2 +1,2 @@ -scarb 2.5.4 -starknet-foundry 0.18.0 \ No newline at end of file +scarb 2.7.1 +starknet-foundry 0.30.0 \ No newline at end of file diff --git a/contracts/README.md b/contracts/README.md index 2dd2e4142..c09c61cbd 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -8,19 +8,21 @@ This repository contains the smart contracts for the Ark Project, a comprehensiv A shared library utilized by both `ark_orderbook` and `ark_starknet` contracts, ensuring consistency and efficiency in operations. -### `ark_orderbook` +### `ark_component` (Component) -- **Description**: The central orderbook smart contract for the Ark Project. -- **Network**: Operates on the Solis L3 network. +- **Description**: Provide Orderbook smart contract component for the Ark Project. - **Functionality**: Manages and processes asset orders within the Ark protocol. ### `ark_starknet` - **Description**: Starknet's primary smart contract for the Ark Project. - **Network**: Designed to run on the Starknet L2 network. -- **Components**: - - **Messaging**: Facilitates communication between Solis, the orderbook and the executor smart contract. - - **Executor**: Executes asset swap orders. +- **Functionality**: delegate assets orders management to `Orderbook` component and executes asset swap orders. + +### `ark_oz` (Component) + +- **Description**: Provide ERC2981 implementation. +- **Functionality**: Fees for a given collection/token ### `ark_tokens` (Testing Only) @@ -28,11 +30,8 @@ A shared library utilized by both `ark_orderbook` and `ark_starknet` contracts, - **Tokens**: - `ERC20`: Standard ERC20 token implementation. - `ERC721`: Standard ERC721 token implementation. - -### `solis` - -- **Role**: Acts as a utility contract for Starknet on the Solis platform. -- **Key Feature**: Generates an ABI that enables Solis to interact seamlessly with Starknet contracts. + - `ERC721Royalty`: ERC721 token implementation with ERC2981 support (`ark_oz` component) + - `ERC1155`: ERC1155 token implementation with ERC1155Receiver support. ## Build Instructions diff --git a/contracts/Scarb.lock b/contracts/Scarb.lock index c8865abf6..4c6997a32 100644 --- a/contracts/Scarb.lock +++ b/contracts/Scarb.lock @@ -9,7 +9,7 @@ dependencies = [ ] [[package]] -name = "ark_orderbook" +name = "ark_component" version = "0.1.0" dependencies = [ "ark_common", @@ -21,7 +21,6 @@ name = "ark_oz" version = "0.1.0" dependencies = [ "openzeppelin", - "snforge_std", ] [[package]] @@ -29,6 +28,7 @@ name = "ark_starknet" version = "0.1.0" dependencies = [ "ark_common", + "ark_component", "ark_oz", "ark_tokens", "openzeppelin", @@ -46,14 +46,98 @@ dependencies = [ [[package]] name = "openzeppelin" -version = "0.10.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.10.0#d77082732daab2690ba50742ea41080eb23299d3" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_access", + "openzeppelin_account", + "openzeppelin_governance", + "openzeppelin_introspection", + "openzeppelin_presets", + "openzeppelin_security", + "openzeppelin_token", + "openzeppelin_upgrades", + "openzeppelin_utils", +] [[package]] -name = "snforge_std" -version = "0.18.0" -source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.18.0#48f909a56b08cbdc5ca6a21a836b0fbc6c36d55b" +name = "openzeppelin_access" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_introspection", + "openzeppelin_utils", +] + +[[package]] +name = "openzeppelin_account" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_introspection", + "openzeppelin_utils", +] + +[[package]] +name = "openzeppelin_governance" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_access", + "openzeppelin_introspection", +] [[package]] -name = "solis" +name = "openzeppelin_introspection" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" + +[[package]] +name = "openzeppelin_presets" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_access", + "openzeppelin_account", + "openzeppelin_introspection", + "openzeppelin_token", + "openzeppelin_upgrades", +] + +[[package]] +name = "openzeppelin_security" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" + +[[package]] +name = "openzeppelin_token" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_account", + "openzeppelin_governance", + "openzeppelin_introspection", +] + +[[package]] +name = "openzeppelin_upgrades" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" + +[[package]] +name = "openzeppelin_utils" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" + +[[package]] +name = "snforge_scarb_plugin" version = "0.1.0" +source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.30.0#196f06b251926697c3d66800f2a93ae595e76496" + +[[package]] +name = "snforge_std" +version = "0.30.0" +source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.30.0#196f06b251926697c3d66800f2a93ae595e76496" +dependencies = [ + "snforge_scarb_plugin", +] diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 83a37c9de..d3a1bbb1b 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -1,6 +1,15 @@ [workspace] -members = ["ark_common", "ark_orderbook", "ark_starknet", "ark_tokens", "solis"] +members = ["ark_common", "ark_component", "ark_starknet", "ark_tokens"] + +[workspace.dependencies] +starknet = "2.7.1" +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.15.1" } +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.30.0" } +assert_macros = "0.1.0" [workspace.scripts] test = "snforge test" + +[workspace.tool.fmt] +sort-module-level-items = true diff --git a/contracts/ark_common/Scarb.toml b/contracts/ark_common/Scarb.toml index 3dca0b95c..d7fa37b83 100644 --- a/contracts/ark_common/Scarb.toml +++ b/contracts/ark_common/Scarb.toml @@ -5,8 +5,13 @@ version = "0.1.0" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -starknet = "2.5.4" -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.18.0" } +starknet.workspace = true + +[dev-dependencies] +snforge_std.workspace = true + +[tool] +fmt.workspace = true [lib] diff --git a/contracts/ark_common/src/crypto/common.cairo b/contracts/ark_common/src/crypto/common.cairo index 8908a61a2..61cf5b5d3 100644 --- a/contracts/ark_common/src/crypto/common.cairo +++ b/contracts/ark_common/src/crypto/common.cairo @@ -1,7 +1,6 @@ -use traits::Into; - // locals use super::constants; +use traits::Into; fn hash_u256(n: u256) -> felt252 { let mut hash = pedersen::pedersen(0, constants::U256_TYPE_HASH); diff --git a/contracts/ark_common/src/crypto/typed_data.cairo b/contracts/ark_common/src/crypto/typed_data.cairo index 1d5389806..c5f24c3a6 100644 --- a/contracts/ark_common/src/crypto/typed_data.cairo +++ b/contracts/ark_common/src/crypto/typed_data.cairo @@ -1,6 +1,6 @@ -use traits::Into; use box::BoxTrait; use super::constants; +use traits::Into; const ORDER_TYPE_HASH: felt252 = 0x3749634CC837ADA5AF76B97FC3197F05DFC376CF4B73199E76107754E39CA1D; diff --git a/contracts/ark_common/src/lib.cairo b/contracts/ark_common/src/lib.cairo index 54eb951bc..8650199ab 100644 --- a/contracts/ark_common/src/lib.cairo +++ b/contracts/ark_common/src/lib.cairo @@ -1,13 +1,13 @@ mod protocol { + mod order_database; mod order_types; mod order_v1; - mod order_database; } mod crypto { + mod common; + mod constants; mod hash; mod signer; mod typed_data; - mod constants; - mod common; } diff --git a/contracts/ark_common/src/protocol/order_database.cairo b/contracts/ark_common/src/protocol/order_database.cairo index 03edefa30..9c71a485f 100644 --- a/contracts/ark_common/src/protocol/order_database.cairo +++ b/contracts/ark_common/src/protocol/order_database.cairo @@ -1,3 +1,5 @@ +use ark_common::protocol::order_types::OrderStatus; +use ark_common::protocol::order_types::OrderType; use core::result::ResultTrait; //! Orders database. //! @@ -20,9 +22,6 @@ use core::result::ResultTrait; //! 4. At base addresss + offset 2 => First felt of the serialized order. use starknet::SyscallResultTrait; -use ark_common::protocol::order_types::OrderStatus; -use ark_common::protocol::order_types::OrderType; - /// Must remain equal to 0 for now. const ADDRESS_DOMAIN: u32 = 0; /// A constant value used in the base key hash. diff --git a/contracts/ark_common/src/protocol/order_types.cairo b/contracts/ark_common/src/protocol/order_types.cairo index cd903c157..f2ffb7eee 100644 --- a/contracts/ark_common/src/protocol/order_types.cairo +++ b/contracts/ark_common/src/protocol/order_types.cairo @@ -1,7 +1,7 @@ +use ark_common::protocol::order_v1::OrderV1; +use poseidon::poseidon_hash_span; //! Order generic variables. use starknet::ContractAddress; -use poseidon::poseidon_hash_span; -use ark_common::protocol::order_v1::OrderV1; /// Order types. #[derive(Serde, Drop, PartialEq, Copy, Debug, starknet::Store)] @@ -207,6 +207,8 @@ struct FulfillInfo { token_address: ContractAddress, // Token token id. token_id: Option, + // The quantity of the token (1 for ERC-721, variable for ERC-1155). + quantity: u256, // Broker address. fulfill_broker_address: ContractAddress, } @@ -216,10 +218,11 @@ struct FulfillInfo { #[derive(Drop, Serde, Copy)] struct ExecutionInfo { order_hash: felt252, - nft_address: ContractAddress, - nft_from: ContractAddress, - nft_to: ContractAddress, - nft_token_id: u256, + token_address: ContractAddress, + token_from: ContractAddress, + token_to: ContractAddress, + token_id: u256, + token_quantity: u256, payment_from: ContractAddress, payment_to: ContractAddress, payment_amount: u256, @@ -262,6 +265,8 @@ enum RouteType { #[default] Erc20ToErc721, Erc721ToErc20, + Erc20ToErc1155, + Erc1155ToErc20, } impl RouteIntoFelt252 of Into { @@ -269,6 +274,8 @@ impl RouteIntoFelt252 of Into { match self { RouteType::Erc20ToErc721 => 'ERC20TOERC721', RouteType::Erc721ToErc20 => 'ERC721TOERC20', + RouteType::Erc20ToErc1155 => 'ERC20TOERC1155', + RouteType::Erc1155ToErc20 => 'ERC1155TOERC20', } } } @@ -279,6 +286,10 @@ impl Felt252TryIntoRoute of TryInto { Option::Some(RouteType::Erc20ToErc721) } else if self == 'ERC721TOERC20' { Option::Some(RouteType::Erc721ToErc20) + } else if self == 'ERC1155TOERC20' { + Option::Some(RouteType::Erc1155ToErc20) + } else if self == 'ERC20TOERC1155' { + Option::Some(RouteType::Erc20ToErc1155) } else { Option::None } diff --git a/contracts/ark_common/src/protocol/order_v1.cairo b/contracts/ark_common/src/protocol/order_v1.cairo index f20bce4dd..b98b39470 100644 --- a/contracts/ark_common/src/protocol/order_v1.cairo +++ b/contracts/ark_common/src/protocol/order_v1.cairo @@ -1,16 +1,16 @@ +use ark_common::protocol::order_types::FulfillInfo; +use ark_common::protocol::order_types::{OrderTrait, OrderValidationError, OrderType, RouteType}; use core::array::ArrayTrait; +use core::option::OptionTrait; use core::traits::Into; use core::traits::TryInto; -use core::option::OptionTrait; +use poseidon::poseidon_hash_span; //! Order v1 supported by the Orderbook. //! use starknet::ContractAddress; -use starknet::contract_address_to_felt252; -use ark_common::protocol::order_types::{OrderTrait, OrderValidationError, OrderType, RouteType}; -use ark_common::protocol::order_types::FulfillInfo; -use poseidon::poseidon_hash_span; use starknet::SyscallResultTrait; +use starknet::contract_address_to_felt252; const ORDER_VERSION_V1: felt252 = 'v1'; // Auction -> end_amount (reserve price) > start_amount (starting price). @@ -100,26 +100,30 @@ impl OrderTraitOrderV1 of OrderTrait { // Listing order. if (*self.start_amount) > 0 && (*self.end_amount).is_zero() - && (*self.route) == RouteType::Erc721ToErc20 { + && ((*self.route) == RouteType::Erc721ToErc20 + || (*self.route) == RouteType::Erc1155ToErc20) { return Result::Ok(OrderType::Listing); } // Offer order. if (*self.start_amount) > 0 && (*self.end_amount).is_zero() - && (*self.route) == RouteType::Erc20ToErc721 { + && ((*self.route) == RouteType::Erc20ToErc721 + || (*self.route) == RouteType::Erc20ToErc1155) { return Result::Ok(OrderType::Offer); } // Auction order. if (*self.start_amount) > 0 && (*self.end_amount) >= (*self.start_amount) - && (*self.route) == RouteType::Erc721ToErc20 { + && ((*self.route) == RouteType::Erc721ToErc20 + || (*self.route) == RouteType::Erc1155ToErc20) { return Result::Ok(OrderType::Auction); } } else { // Collection Offer order. if (*self.start_amount) > 0 && (*self.end_amount).is_zero() - && (*self.route) == RouteType::Erc20ToErc721 { + && ((*self.route) == RouteType::Erc20ToErc721 + || (*self.route) == RouteType::Erc20ToErc1155) { return Result::Ok(OrderType::CollectionOffer); } } diff --git a/contracts/ark_common/tests/test_type_data.cairo b/contracts/ark_common/tests/test_type_data.cairo index 7bacb6563..b4b8116b1 100644 --- a/contracts/ark_common/tests/test_type_data.cairo +++ b/contracts/ark_common/tests/test_type_data.cairo @@ -1,19 +1,19 @@ -use core::traits::TryInto; -use traits::Into; -use box::BoxTrait; +use ark_common::crypto::signer::{Signer, SignInfo}; use ark_common::crypto::typed_data::{OrderSign, TypedDataTrait}; +use box::BoxTrait; use core::option::OptionTrait; -use ark_common::crypto::signer::{Signer, SignInfo}; +use core::traits::TryInto; use snforge_std::signature::KeyPairTrait; use snforge_std::signature::stark_curve::{ StarkCurveKeyPairImpl, StarkCurveSignerImpl, StarkCurveVerifierImpl }; +use traits::Into; fn sign_mock(message_hash: felt252) -> Signer { let key_pair = KeyPairTrait::::generate(); - let (r, s): (felt252, felt252) = key_pair.sign(message_hash); + let (r, s): (felt252, felt252) = key_pair.sign(message_hash).unwrap(); Signer::WEIERSTRESS_STARKNET( SignInfo { user_pubkey: key_pair.public_key, user_sig_r: r, user_sig_s: s, } ) diff --git a/contracts/ark_component/Scarb.toml b/contracts/ark_component/Scarb.toml new file mode 100644 index 000000000..4f922c2c0 --- /dev/null +++ b/contracts/ark_component/Scarb.toml @@ -0,0 +1,19 @@ +[package] +name = "ark_component" +version = "0.1.0" + +[dependencies] +ark_common = { path = "../ark_common" } +starknet.workspace = true + +[dev-dependencies] +snforge_std.workspace = true +assert_macros.workspace = true + +[scripts] +test.workspace = true + +[tool] +fmt.workspace = true + +[lib] diff --git a/contracts/ark_component/src/lib.cairo b/contracts/ark_component/src/lib.cairo new file mode 100644 index 000000000..959ef2db9 --- /dev/null +++ b/contracts/ark_component/src/lib.cairo @@ -0,0 +1 @@ +mod orderbook; diff --git a/contracts/ark_component/src/orderbook.cairo b/contracts/ark_component/src/orderbook.cairo new file mode 100644 index 000000000..191215137 --- /dev/null +++ b/contracts/ark_component/src/orderbook.cairo @@ -0,0 +1,9 @@ +pub mod interface; +pub mod orderbook; +pub use interface::{IOrderbook, IOrderbookAction, orderbook_errors}; + +pub use orderbook::OrderbookComponent; +pub use orderbook::{ + OrderbookHooksCreateOrderEmptyImpl, OrderbookHooksCancelOrderEmptyImpl, + OrderbookHooksFulfillOrderEmptyImpl, OrderbookHooksValidateOrderExecutionEmptyImpl, +}; diff --git a/contracts/ark_component/src/orderbook/interface.cairo b/contracts/ark_component/src/orderbook/interface.cairo new file mode 100644 index 000000000..b8d6fa501 --- /dev/null +++ b/contracts/ark_component/src/orderbook/interface.cairo @@ -0,0 +1,80 @@ +use ark_common::protocol::order_types::{ + CancelInfo, ExecutionInfo, ExecutionValidationInfo, FulfillInfo, OrderStatus, OrderType +}; +use ark_common::protocol::order_v1::OrderV1; + +use starknet::ContractAddress; + +// ************************************************************************* +// ERRORS +// +// Error messages used within the orderbook contract. +// ************************************************************************* +pub mod orderbook_errors { + const BROKER_UNREGISTERED: felt252 = 'OB: unregistered broker'; + const ORDER_INVALID_DATA: felt252 = 'OB: order invalid data'; + const ORDER_ALREADY_EXISTS: felt252 = 'OB: order already exists'; + const ORDER_ALREADY_EXEC: felt252 = 'OB: order already executed'; + const ORDER_NOT_FULFILLABLE: felt252 = 'OB: order not fulfillable'; + const ORDER_NOT_FOUND: felt252 = 'OB: order not found'; + const ORDER_FULFILLED: felt252 = 'OB: order fulfilled'; + const ORDER_NOT_CANCELLABLE: felt252 = 'OB: order not cancellable'; + const ORDER_EXPIRED: felt252 = 'OB: order expired'; + const ORDER_SAME_OFFERER: felt252 = 'OB: order has same offerer'; + const ORDER_NOT_SAME_OFFERER: felt252 = 'OB: fulfiller is not offerer'; + const OFFER_ALREADY_EXISTS: felt252 = 'OB: offer already exists'; + const ORDER_IS_EXPIRED: felt252 = 'OB: order is expired'; + const ORDER_AUCTION_IS_EXPIRED: felt252 = 'OB: auction is expired'; + const ORDER_MISSING_RELATED_ORDER: felt252 = 'OB: order missing related order'; + const ORDER_HASH_DOES_NOT_MATCH: felt252 = 'OB: order hash does not match'; + const ORDER_TOKEN_ID_DOES_NOT_MATCH: felt252 = 'OB: token id does not match'; + const ORDER_TOKEN_ID_IS_MISSING: felt252 = 'OB: token id is missing'; + const ORDER_TOKEN_HASH_DOES_NOT_MATCH: felt252 = 'OB: token hash does not match'; + const ORDER_NOT_AN_OFFER: felt252 = 'OB: order is not an offer'; + const ORDER_NOT_OPEN: felt252 = 'OB: order is not open'; + const ORDER_OPEN: felt252 = 'OB: order is not open'; + const USE_FULFILL_AUCTION: felt252 = 'OB: must use fulfill auction'; + const OFFER_NOT_STARTED: felt252 = 'OB: offer is not started'; + const INVALID_BROKER: felt252 = 'OB: broker is not whitelisted'; +} + +#[starknet::interface] +pub trait IOrderbook { + /// Retrieves the type of an order using its hash. + /// + /// # Arguments + /// * `order_hash` - The order hash of order. + fn get_order_type(self: @T, order_hash: felt252) -> OrderType; + + /// Retrieves the status of an order using its hash. + /// + /// # Arguments + /// * `order_hash` - The order hash of order. + fn get_order_status(self: @T, order_hash: felt252) -> OrderStatus; + + /// Retrieves the auction end date. + /// + /// # Arguments + /// * `order_hash` - The order hash of order. + fn get_auction_expiration(self: @T, order_hash: felt252) -> u64; + + /// Retrieves the order using its hash. + /// + /// # Arguments + /// * `order_hash` - The order hash of order. + fn get_order(self: @T, order_hash: felt252) -> OrderV1; + + /// Retrieves the order hash using its token hash. + /// + /// # Arguments + /// * `token_hash` - The token hash of the order. + fn get_order_hash(self: @T, token_hash: felt252) -> felt252; +} + +pub trait IOrderbookAction { + fn validate_order_execution(ref self: T, info: ExecutionValidationInfo); + + fn create_order(ref self: T, order: OrderV1); + fn cancel_order(ref self: T, cancel_info: CancelInfo); + fn fulfill_order(ref self: T, fulfill_info: FulfillInfo) -> Option::; +} diff --git a/contracts/ark_orderbook/src/orderbook.cairo b/contracts/ark_component/src/orderbook/orderbook.cairo similarity index 62% rename from contracts/ark_orderbook/src/orderbook.cairo rename to contracts/ark_component/src/orderbook/orderbook.cairo index 3db6318de..19320c6c6 100644 --- a/contracts/ark_orderbook/src/orderbook.cairo +++ b/contracts/ark_component/src/orderbook/orderbook.cairo @@ -1,137 +1,38 @@ -//! # Orderbook Contract -//! -//! This module defines the structure and functionalities of an orderbook contract. It includes -//! trait definitions, error handling, contract storage, events, constructors, L1 handlers, external functions, -//! and internal functions. The primary functionalities include broker whitelisting, order management -//! (creation, cancellation, fulfillment), and order queries. - -use ark_common::protocol::order_types::{FulfillInfo, OrderType, CancelInfo, OrderStatus}; -use ark_common::crypto::signer::{SignInfo, Signer, SignerValidator}; -use ark_common::protocol::order_v1::OrderV1; -use starknet::ContractAddress; - -/// Orderbook trait to define operations on orderbooks. -#[starknet::interface] -trait Orderbook { - /// Retrieves the type of an order using its hash. - /// - /// # Arguments - /// * `order_hash` - The order hash of order. - fn get_order_type(self: @T, order_hash: felt252) -> OrderType; - - /// Retrieves the status of an order using its hash. - /// - /// # Arguments - /// * `order_hash` - The order hash of order. - fn get_order_status(self: @T, order_hash: felt252) -> OrderStatus; - - /// Retrieves the auction end date. - /// - /// # Arguments - /// * `order_hash` - The order hash of order. - fn get_auction_expiration(self: @T, order_hash: felt252) -> u64; - - /// Retrieves the order using its hash. - /// - /// # Arguments - /// * `order_hash` - The order hash of order. - fn get_order(self: @T, order_hash: felt252) -> OrderV1; - - /// Retrieves the order hash using its token hash. - /// - /// # Arguments - /// * `token_hash` - The token hash of the order. - fn get_order_hash(self: @T, token_hash: felt252) -> felt252; - - /// Upgrades the contract to a new version. - /// - /// # Arguments - /// * `class_hash` - The class hash of the new contract version. - fn upgrade(ref self: T, class_hash: starknet::ClassHash); - - fn update_starknet_executor_address(ref self: T, value: starknet::ContractAddress); -} - -// ************************************************************************* -// ERRORS -// -// Error messages used within the orderbook contract. -// ************************************************************************* -mod orderbook_errors { - const BROKER_UNREGISTERED: felt252 = 'OB: unregistered broker'; - const ORDER_INVALID_DATA: felt252 = 'OB: order invalid data'; - const ORDER_ALREADY_EXISTS: felt252 = 'OB: order already exists'; - const ORDER_ALREADY_EXEC: felt252 = 'OB: order already executed'; - const ORDER_NOT_FULFILLABLE: felt252 = 'OB: order not fulfillable'; - const ORDER_NOT_FOUND: felt252 = 'OB: order not found'; - const ORDER_FULFILLED: felt252 = 'OB: order fulfilled'; - const ORDER_NOT_CANCELLABLE: felt252 = 'OB: order not cancellable'; - const ORDER_EXPIRED: felt252 = 'OB: order expired'; - const ORDER_SAME_OFFERER: felt252 = 'OB: order has same offerer'; - const ORDER_NOT_SAME_OFFERER: felt252 = 'OB: fulfiller is not offerer'; - const OFFER_ALREADY_EXISTS: felt252 = 'OB: offer already exists'; - const ORDER_IS_EXPIRED: felt252 = 'OB: order is expired'; - const ORDER_AUCTION_IS_EXPIRED: felt252 = 'OB: auction is expired'; - const ORDER_MISSING_RELATED_ORDER: felt252 = 'OB: order missing related order'; - const ORDER_HASH_DOES_NOT_MATCH: felt252 = 'OB: order hash does not match'; - const ORDER_TOKEN_ID_DOES_NOT_MATCH: felt252 = 'OB: token id does not match'; - const ORDER_TOKEN_ID_IS_MISSING: felt252 = 'OB: token id is missing'; - const ORDER_TOKEN_HASH_DOES_NOT_MATCH: felt252 = 'OB: token hash does not match'; - const ORDER_NOT_AN_OFFER: felt252 = 'OB: order is not an offer'; - const ORDER_NOT_OPEN: felt252 = 'OB: order is not open'; - const ORDER_OPEN: felt252 = 'OB: order is not open'; - const USE_FULFILL_AUCTION: felt252 = 'OB: must use fulfill auction'; - const OFFER_NOT_STARTED: felt252 = 'OB: offer is not started'; - const INVALID_BROKER: felt252 = 'OB: broker is not whitelisted'; -} - -/// StarkNet smart contract module for an order book. -#[starknet::contract] -mod orderbook { - use ark_common::crypto::typed_data::{OrderSign, TypedDataTrait}; - use core::debug::PrintTrait; - use ark_common::crypto::signer::{SignInfo, Signer, SignerTrait, SignerValidator}; +#[starknet::component] +pub mod OrderbookComponent { + use ark_common::protocol::order_database::{ + order_read, order_status_read, order_write, order_status_write, order_type_read + }; use ark_common::protocol::order_types::{ OrderStatus, OrderTrait, OrderType, CancelInfo, FulfillInfo, ExecutionValidationInfo, ExecutionInfo, RouteType }; - use ark_common::crypto::hash::{serialized_hash}; - use core::traits::TryInto; - use core::result::ResultTrait; - use core::zeroable::Zeroable; + use ark_common::protocol::order_v1::OrderV1; + use core::debug::PrintTrait; use core::option::OptionTrait; + use core::result::ResultTrait; use core::starknet::event::EventEmitter; use core::traits::Into; - use super::{orderbook_errors, Orderbook}; + use core::traits::TryInto; + use core::zeroable::Zeroable; use starknet::ContractAddress; - use ark_common::protocol::order_v1::OrderV1; - use ark_common::protocol::order_database::{ - order_read, order_status_read, order_write, order_status_write, order_type_read - }; + use starknet::storage::Map; + use super::super::interface::{IOrderbook, IOrderbookAction, orderbook_errors}; const EXTENSION_TIME_IN_SECONDS: u64 = 600; const AUCTION_ACCEPTING_TIME_SECS: u64 = 172800; - /// Storage struct for the Orderbook contract. + /// Storage struct for the Orderbook component. #[storage] struct Storage { - /// Order database. - /// Mapping of token hashes to order data. - /// Order database [token_hash, order_data] - /// see ark_orderbook:order::database for more details. - chain_id: felt252, - /// Administrator address of the order book. - admin: ContractAddress, /// Mapping of broker addresses to their whitelisted status. /// Represented as felt252, set to 1 if the broker is registered. - brokers: LegacyMap, + brokers: Map, /// Mapping of token_hash to order_hash. - token_listings: LegacyMap, + token_listings: Map, /// Mapping of token_hash to auction details (order_hash and end_date, auction_offer_count). - auctions: LegacyMap, + auctions: Map, /// Mapping of auction offer order_hash to auction listing order_hash. - auction_offers: LegacyMap, - /// The address of the StarkNet executor contract. - starknet_executor_address: ContractAddress, + auction_offers: Map, } // ************************************************************************* @@ -141,24 +42,26 @@ mod orderbook { /// Events emitted by the Orderbook contract. #[event] #[derive(Drop, starknet::Event)] - enum Event { + pub enum Event { OrderPlaced: OrderPlaced, OrderExecuted: OrderExecuted, OrderCancelled: OrderCancelled, RollbackStatus: RollbackStatus, - OrderFulfilled: OrderFulfilled, - Upgraded: Upgraded, } + // must be increased when `OrderPlaced` content change + pub const ORDER_PLACED_EVENT_VERSION: u8 = 1; /// Event for when an order is placed. #[derive(Drop, starknet::Event)] - struct OrderPlaced { + pub struct OrderPlaced { #[key] order_hash: felt252, #[key] order_version: felt252, #[key] order_type: OrderType, + /// + version: u8, // The order that was cancelled by this order. cancelled_order_hash: Option, // The full order serialized. @@ -166,145 +69,87 @@ mod orderbook { } // must be increased when `OrderExecuted` content change - const ORDER_EXECUTED_EVENT_VERSION: u8 = 1; + pub const ORDER_EXECUTED_EVENT_VERSION: u8 = 2; /// Event for when an order is executed. #[derive(Drop, starknet::Event)] - struct OrderExecuted { + pub struct OrderExecuted { #[key] order_hash: felt252, #[key] order_status: OrderStatus, + #[key] + order_type: OrderType, + /// version: u8, transaction_hash: felt252, from: ContractAddress, to: ContractAddress, } + // must be increased when `OrderPlaced` content change + pub const ORDER_CANCELLED_EVENT_VERSION: u8 = 1; /// Event for when an order is cancelled. #[derive(Drop, starknet::Event)] - struct OrderCancelled { + pub struct OrderCancelled { #[key] order_hash: felt252, #[key] reason: felt252, - } - - /// Event for when an order has been rollbacked to placed. - #[derive(Drop, starknet::Event)] - struct RollbackStatus { - #[key] - order_hash: felt252, #[key] - reason: felt252 + order_type: OrderType, + version: u8, } - /// Event for when an order is fulfilled. + // must be increased when `RollbackStatus` content change + pub const ROLLBACK_STATUS_EVENT_VERSION: u8 = 1; + /// Event for when an order has been rollbacked to placed. #[derive(Drop, starknet::Event)] - struct OrderFulfilled { + pub struct RollbackStatus { #[key] order_hash: felt252, #[key] - fulfiller: ContractAddress, + reason: felt252, #[key] - related_order_hash: Option, - } - - #[derive(Drop, starknet::Event)] - struct Upgraded { - class_hash: starknet::ClassHash, - } - - // ************************************************************************* - // CONSTRUCTOR - // ************************************************************************* - #[constructor] - fn constructor(ref self: ContractState, admin: ContractAddress, chain_id: felt252) { - self.admin.write(admin); - self.chain_id.write(chain_id); - } - - // ************************************************************************* - // L1 HANDLERS - // Only the sequencer can call this function with L1HandlerTransaction. - // ************************************************************************* - - /// L1 handler for placing an order. - /// # TODO - /// * Verify it comes from Arkchain executor contract. - /// * Check data + cancel / execute the order. - #[l1_handler] - fn validate_order_execution( - ref self: ContractState, _from_address: felt252, info: ExecutionValidationInfo - ) { - // Solis already checks that ALL the messages are coming from the executor contract. - // TODO: anyway, it can be useful to have an extra check here. - order_status_write(info.order_hash, OrderStatus::Executed); - let order_status = order_status_read(info.order_hash).unwrap(); - self - .emit( - OrderExecuted { - order_hash: info.order_hash, - order_status: order_status, - transaction_hash: info.transaction_hash, - from: info.from, - to: info.to, - version: ORDER_EXECUTED_EVENT_VERSION, - } - ); + order_type: OrderType, + /// + version: u8, } - /// Update status : only from solis. - #[l1_handler] - fn rollback_status_order( - ref self: ContractState, _from_address: felt252, order_hash: felt252, reason: felt252 - ) { - order_status_write(order_hash, OrderStatus::Open); - self.emit(RollbackStatus { order_hash, reason: reason.into() }); + pub trait OrderbookHooksCreateOrderTrait { + fn before_create_order(ref self: ComponentState, order: OrderV1) {} + fn after_create_order(ref self: ComponentState, order: OrderV1) {} } - #[l1_handler] - fn create_order_from_l2(ref self: ContractState, _from_address: felt252, order: OrderV1) { - self._create_order(order); + pub trait OrderbookHooksCancelOrderTrait { + fn before_cancel_order(ref self: ComponentState, cancel_info: CancelInfo) {} + fn after_cancel_order(ref self: ComponentState, cancel_info: CancelInfo) {} } - #[l1_handler] - fn cancel_order_from_l2( - ref self: ContractState, _from_address: felt252, cancelInfo: CancelInfo - ) { - self._cancel_order(cancelInfo); + pub trait OrderbookHooksFulfillOrderTrait { + fn before_fulfill_order( + ref self: ComponentState, fulfill_info: FulfillInfo + ) {} + fn after_fulfill_order( + ref self: ComponentState, fulfill_info: FulfillInfo + ) {} } - #[l1_handler] - fn fulfill_order_from_l2( - ref self: ContractState, _from_address: felt252, fulfillInfo: FulfillInfo - ) { - self._fulfill_order(fulfillInfo); + pub trait OrderbookHooksValidateOrderExecutionTrait { + fn before_validate_order_execution( + ref self: ComponentState, info: ExecutionValidationInfo + ) {} + fn after_validate_order_execution( + ref self: ComponentState, info: ExecutionValidationInfo + ) {} } - // ************************************************************************* - // EXTERNAL FUNCTIONS - // ************************************************************************* - #[abi(embed_v0)] - impl ImplOrderbook of Orderbook { - fn upgrade(ref self: ContractState, class_hash: starknet::ClassHash) { - assert( - starknet::get_caller_address() == self.admin.read(), 'Unauthorized replace class' - ); - - match starknet::replace_class_syscall(class_hash) { - Result::Ok(_) => self.emit(Upgraded { class_hash }), - Result::Err(revert_reason) => panic(revert_reason), - }; - } - - fn update_starknet_executor_address(ref self: ContractState, value: ContractAddress) { - assert(starknet::get_caller_address() == self.admin.read(), 'Unauthorized update'); - self.starknet_executor_address.write(value); - } - + #[embeddable_as(OrderbookImpl)] + pub impl Orderbook< + TContractState, +HasComponent, +Drop, + > of IOrderbook> { /// Retrieves the type of an order using its hash. /// # View - fn get_order_type(self: @ContractState, order_hash: felt252) -> OrderType { + fn get_order_type(self: @ComponentState, order_hash: felt252) -> OrderType { let order_type_option = order_type_read(order_hash); if order_type_option.is_none() { panic_with_felt252(orderbook_errors::ORDER_NOT_FOUND); @@ -314,7 +159,9 @@ mod orderbook { /// Retrieves the status of an order using its hash. /// # View - fn get_order_status(self: @ContractState, order_hash: felt252) -> OrderStatus { + fn get_order_status( + self: @ComponentState, order_hash: felt252 + ) -> OrderStatus { let status = order_status_read(order_hash); if status.is_none() { panic_with_felt252(orderbook_errors::ORDER_NOT_FOUND); @@ -324,19 +171,21 @@ mod orderbook { /// Retrieves the auction end date /// # View - fn get_auction_expiration(self: @ContractState, order_hash: felt252) -> u64 { + fn get_auction_expiration( + self: @ComponentState, order_hash: felt252 + ) -> u64 { let order = order_read::(order_hash); if (order.is_none()) { panic_with_felt252(orderbook_errors::ORDER_NOT_FOUND); } let token_hash = order.unwrap().compute_token_hash(); - let (_, auction_end_date, _) = self.auctions.read(token_hash); + let (_, auction_end_date, _b) = self.auctions.read(token_hash); auction_end_date } /// Retrieves the order using its hash. /// # View - fn get_order(self: @ContractState, order_hash: felt252) -> OrderV1 { + fn get_order(self: @ComponentState, order_hash: felt252) -> OrderV1 { let order = order_read(order_hash); if (order.is_none()) { panic_with_felt252(orderbook_errors::ORDER_NOT_FOUND); @@ -346,7 +195,7 @@ mod orderbook { /// Retrieves the order hash using its token hash. /// # View - fn get_order_hash(self: @ContractState, token_hash: felt252) -> felt252 { + fn get_order_hash(self: @ComponentState, token_hash: felt252) -> felt252 { let order_hash = self.token_listings.read(token_hash); if (order_hash.is_zero()) { panic_with_felt252(orderbook_errors::ORDER_NOT_FOUND); @@ -355,13 +204,67 @@ mod orderbook { } } - // ************************************************************************* - // INTERNAL FUNCTIONS - // ************************************************************************* - #[generate_trait] - impl InternalFunctions of InternalFunctionsTrait { - // TODO: kwiss this code repeat itself with the public function, we should refactor it. - fn _cancel_order(ref self: ContractState, cancel_info: CancelInfo) { + pub impl OrderbookActionImpl< + TContractState, + +HasComponent, + impl HooksCreateOrder: OrderbookHooksCreateOrderTrait, + impl HooksCancelOrder: OrderbookHooksCancelOrderTrait, + impl HooksFulfillOrder: OrderbookHooksFulfillOrderTrait, + impl HooksValidateOrder: OrderbookHooksValidateOrderExecutionTrait, + > of IOrderbookAction> { + fn validate_order_execution( + ref self: ComponentState, info: ExecutionValidationInfo + ) { + HooksValidateOrder::before_validate_order_execution(ref self, info); + order_status_write(info.order_hash, OrderStatus::Executed); + let order_status = order_status_read(info.order_hash).unwrap(); + let order_type = order_type_read(info.order_hash).unwrap(); + self + .emit( + OrderExecuted { + order_hash: info.order_hash, + order_status, + order_type, + transaction_hash: info.transaction_hash, + from: info.from, + to: info.to, + version: ORDER_EXECUTED_EVENT_VERSION, + } + ); + + HooksValidateOrder::after_validate_order_execution(ref self, info); + } + + /// Submits and places an order to the orderbook if the order is valid. + fn create_order(ref self: ComponentState, order: OrderV1) { + HooksCreateOrder::before_create_order(ref self, order); + let block_ts = starknet::get_block_timestamp(); + let validation = order.validate_common_data(block_ts); + if validation.is_err() { + panic_with_felt252(validation.unwrap_err().into()); + } + let order_type = order + .validate_order_type() + .expect(orderbook_errors::ORDER_INVALID_DATA); + let order_hash = order.compute_order_hash(); + assert(order_status_read(order_hash).is_none(), orderbook_errors::ORDER_ALREADY_EXISTS); + match order_type { + OrderType::Listing => { + let _ = self._create_listing_order(order, order_type, order_hash); + }, + OrderType::Auction => { self._create_auction(order, order_type, order_hash); }, + OrderType::Offer => { self._create_offer(order, order_type, order_hash); }, + OrderType::CollectionOffer => { + self._create_collection_offer(order, order_type, order_hash); + }, + }; + + HooksCreateOrder::after_create_order(ref self, order); + } + + fn cancel_order(ref self: ComponentState, cancel_info: CancelInfo) { + HooksCancelOrder::before_cancel_order(ref self, cancel_info); + let order_hash = cancel_info.order_hash; let order_option = order_read::(order_hash); assert(order_option.is_some(), orderbook_errors::ORDER_NOT_FOUND); @@ -372,7 +275,7 @@ mod orderbook { Option::None => panic_with_felt252(orderbook_errors::ORDER_NOT_FOUND), }; let block_ts = starknet::get_block_timestamp(); - match order_type_read(order_hash) { + let order_type = match order_type_read(order_hash) { Option::Some(order_type) => { if order_type == OrderType::Auction { let auction_token_hash = order.compute_token_hash(); @@ -387,49 +290,31 @@ mod orderbook { self.token_listings.write(order.compute_token_hash(), 0); } } + order_type }, Option::None => panic_with_felt252(orderbook_errors::ORDER_NOT_FOUND), }; // Cancel order order_status_write(order_hash, OrderStatus::CancelledUser); - self.emit(OrderCancelled { order_hash, reason: OrderStatus::CancelledUser.into() }); - } + self + .emit( + OrderCancelled { + order_hash, + reason: OrderStatus::CancelledUser.into(), + order_type, + version: ORDER_CANCELLED_EVENT_VERSION, + } + ); - /// Submits and places an order to the orderbook if the order is valid. - fn _create_order(ref self: ContractState, order: OrderV1) { - let block_ts = starknet::get_block_timestamp(); - let validation = order.validate_common_data(block_ts); - if validation.is_err() { - panic_with_felt252(validation.unwrap_err().into()); - } - let order_type = order - .validate_order_type() - .expect(orderbook_errors::ORDER_INVALID_DATA); - let order_hash = order.compute_order_hash(); - match order_type { - OrderType::Listing => { - assert( - order_status_read(order_hash).is_none(), - orderbook_errors::ORDER_ALREADY_EXISTS - ); - let _ = self._create_listing_order(order, order_type, order_hash); - }, - OrderType::Auction => { - assert( - order_status_read(order_hash).is_none(), - orderbook_errors::ORDER_ALREADY_EXISTS - ); - self._create_auction(order, order_type, order_hash); - }, - OrderType::Offer => { self._create_offer(order, order_type, order_hash); }, - OrderType::CollectionOffer => { - self._create_collection_offer(order, order_type, order_hash); - }, - }; + HooksCancelOrder::after_cancel_order(ref self, cancel_info); } - fn _fulfill_order(ref self: ContractState, fulfill_info: FulfillInfo) { + fn fulfill_order( + ref self: ComponentState, fulfill_info: FulfillInfo + ) -> Option:: { + HooksFulfillOrder::before_fulfill_order(ref self, fulfill_info); + let order_hash = fulfill_info.order_hash; let order: OrderV1 = match order_read(order_hash) { Option::Some(o) => o, @@ -444,14 +329,24 @@ mod orderbook { Option::Some(s) => s, Option::None => panic_with_felt252(orderbook_errors::ORDER_NOT_FOUND), }; - match order_type { - OrderType::Listing => { self._fulfill_listing_order(fulfill_info, order); }, - OrderType::Auction => { self._fulfill_auction_order(fulfill_info, order) }, - OrderType::Offer => { self._fulfill_offer(fulfill_info, order); }, - OrderType::CollectionOffer => { self._fulfill_offer(fulfill_info, order); } - } + let (execution_info, _related_order_hash) = match order_type { + OrderType::Listing => self._fulfill_listing_order(fulfill_info, order), + OrderType::Auction => self._fulfill_auction_order(fulfill_info, order), + OrderType::Offer => self._fulfill_offer(fulfill_info, order), + OrderType::CollectionOffer => self._fulfill_offer(fulfill_info, order), + }; + HooksFulfillOrder::after_fulfill_order(ref self, fulfill_info); + execution_info } + } + // ************************************************************************* + // INTERNAL FUNCTIONS + // ************************************************************************* + #[generate_trait] + pub impl InternalImpl< + TContractState, +HasComponent + > of InternalTrait { /// Fulfill auction order /// /// # Arguments @@ -459,8 +354,8 @@ mod orderbook { /// * `order_type` - The type of the order. /// fn _fulfill_auction_order( - ref self: ContractState, fulfill_info: FulfillInfo, order: OrderV1 - ) { + ref self: ComponentState, fulfill_info: FulfillInfo, order: OrderV1 + ) -> (Option, Option) { let block_timestamp = starknet::get_block_timestamp(); assert( order.offerer == fulfill_info.fulfiller, orderbook_errors::ORDER_NOT_SAME_OFFERER @@ -521,29 +416,15 @@ mod orderbook { order_status_write(related_order_hash, OrderStatus::Fulfilled); order_status_write(fulfill_info.order_hash, OrderStatus::Fulfilled); - self - .emit( - OrderFulfilled { - order_hash: fulfill_info.order_hash, - fulfiller: fulfill_info.fulfiller, - related_order_hash: Option::Some(related_order_hash) - } - ); - let execute_order_selector = selector!("execute_order"); - let starknet_executor_address: ContractAddress = self.starknet_executor_address.read(); - - let mut buf: Array = array![ - starknet_executor_address.into(), execute_order_selector - ]; - // execute order if order.token_id.is_some() { let execute_info = ExecutionInfo { order_hash: order.compute_order_hash(), - nft_address: order.token_address, - nft_from: order.offerer, - nft_to: related_order.offerer, - nft_token_id: order.token_id.unwrap(), + token_address: order.token_address, + token_from: order.offerer, + token_to: related_order.offerer, + token_id: order.token_id.unwrap(), + token_quantity: order.quantity, payment_from: related_order.offerer, payment_to: fulfill_info.fulfiller, payment_amount: related_order.start_amount, @@ -552,8 +433,9 @@ mod orderbook { listing_broker_address: order.broker_id, fulfill_broker_address: fulfill_info.fulfill_broker_address }; - execute_info.serialize(ref buf); - starknet::send_message_to_l1_syscall('EXE', buf.span()).unwrap(); + (Option::Some(execute_info), Option::Some(related_order_hash)) + } else { + (Option::None, Option::Some(related_order_hash)) } } @@ -563,7 +445,9 @@ mod orderbook { /// * `fulfill_info` - The execution info of the order. /// * `order` - The order. /// - fn _fulfill_offer(ref self: ContractState, fulfill_info: FulfillInfo, order: OrderV1) { + fn _fulfill_offer( + ref self: ComponentState, fulfill_info: FulfillInfo, order: OrderV1 + ) -> (Option, Option) { if order.token_id.is_some() { let (auction_order_hash, _, _) = self.auctions.read(order.compute_token_hash()); @@ -574,34 +458,20 @@ mod orderbook { let current_date = starknet::get_block_timestamp(); assert(order.end_date > current_date, orderbook_errors::ORDER_EXPIRED); - order_status_write(fulfill_info.order_hash, OrderStatus::Fulfilled); - self - .emit( - OrderFulfilled { - order_hash: fulfill_info.order_hash, - fulfiller: fulfill_info.fulfiller, - related_order_hash: Option::None - } - ); - - let execute_order_selector = selector!("execute_order"); - let starknet_executor_address: ContractAddress = self.starknet_executor_address.read(); - - let mut buf: Array = array![ - starknet_executor_address.into(), execute_order_selector - ]; if order.token_id.is_some() { // remove token from listed tokens self.token_listings.write(order.compute_token_hash(), 0); } + let execute_info = ExecutionInfo { order_hash: order.compute_order_hash(), - nft_address: order.token_address, - nft_from: fulfill_info.fulfiller, - nft_to: order.offerer, - nft_token_id: fulfill_info.token_id.unwrap(), + token_address: order.token_address, + token_from: fulfill_info.fulfiller, + token_to: order.offerer, + token_id: fulfill_info.token_id.unwrap(), + token_quantity: order.quantity, payment_from: order.offerer, payment_to: fulfill_info.fulfiller, payment_amount: order.start_amount, @@ -610,8 +480,7 @@ mod orderbook { listing_broker_address: order.broker_id, fulfill_broker_address: fulfill_info.fulfill_broker_address }; - execute_info.serialize(ref buf); - starknet::send_message_to_l1_syscall('EXE', buf.span()).unwrap(); + (Option::Some(execute_info), Option::None) } /// Fulfill listing order @@ -621,36 +490,22 @@ mod orderbook { /// * `order_type` - The type of the order. /// fn _fulfill_listing_order( - ref self: ContractState, fulfill_info: FulfillInfo, order: OrderV1 - ) { + ref self: ComponentState, fulfill_info: FulfillInfo, order: OrderV1 + ) -> (Option, Option) { assert(order.offerer != fulfill_info.fulfiller, orderbook_errors::ORDER_SAME_OFFERER); assert( order.end_date > starknet::get_block_timestamp(), orderbook_errors::ORDER_EXPIRED ); order_status_write(fulfill_info.order_hash, OrderStatus::Fulfilled); - self - .emit( - OrderFulfilled { - order_hash: fulfill_info.order_hash, - fulfiller: fulfill_info.fulfiller, - related_order_hash: Option::None - } - ); - - let execute_order_selector = selector!("execute_order"); - let starknet_executor_address: ContractAddress = self.starknet_executor_address.read(); - - let mut buf: Array = array![ - starknet_executor_address.into(), execute_order_selector - ]; if order.token_id.is_some() { let execute_info = ExecutionInfo { order_hash: order.compute_order_hash(), - nft_address: order.token_address, - nft_from: order.offerer, - nft_to: fulfill_info.fulfiller, - nft_token_id: order.token_id.unwrap(), + token_address: order.token_address, + token_from: order.offerer, + token_to: fulfill_info.fulfiller, + token_id: order.token_id.unwrap(), + token_quantity: order.quantity, payment_from: fulfill_info.fulfiller, payment_to: order.offerer, payment_amount: order.start_amount, @@ -659,8 +514,9 @@ mod orderbook { listing_broker_address: order.broker_id, fulfill_broker_address: fulfill_info.fulfill_broker_address }; - execute_info.serialize(ref buf); - starknet::send_message_to_l1_syscall('EXE', buf.span()).unwrap(); + (Option::Some(execute_info), Option::None) + } else { + (Option::None, Option::None) } } @@ -669,7 +525,9 @@ mod orderbook { /// # Arguments /// * `token_hash` - The token hash of the order. /// - fn _get_order_hash_from_token_hash(self: @ContractState, token_hash: felt252) -> felt252 { + fn _get_order_hash_from_token_hash( + self: @ComponentState, token_hash: felt252 + ) -> felt252 { self.token_listings.read(token_hash) } @@ -683,7 +541,7 @@ mod orderbook { /// * is_order_expired /// * order fn _get_previous_order( - self: @ContractState, token_hash: felt252 + self: @ComponentState, token_hash: felt252 ) -> Option<(felt252, bool, OrderV1)> { let previous_listing_orderhash = self.token_listings.read(token_hash); let (previous_auction_orderhash, _, _) = self.auctions.read(token_hash); @@ -725,7 +583,7 @@ mod orderbook { /// * `token_hash` - The token hash of the order. /// fn _process_previous_order( - ref self: ContractState, token_hash: felt252, offerer: ContractAddress + ref self: ComponentState, token_hash: felt252, offerer: ContractAddress ) -> Option { let previous_order = self._get_previous_order(token_hash); if (previous_order.is_some()) { @@ -748,7 +606,10 @@ mod orderbook { /// Creates a listing order. fn _create_listing_order( - ref self: ContractState, order: OrderV1, order_type: OrderType, order_hash: felt252, + ref self: ComponentState, + order: OrderV1, + order_type: OrderType, + order_hash: felt252, ) -> Option { let token_hash = order.compute_token_hash(); // revert if order is fulfilled or Open @@ -775,12 +636,25 @@ mod orderbook { let cancelled_order_hash = self._process_previous_order(token_hash, order.offerer); order_write(order_hash, order_type, order); self.token_listings.write(token_hash, order_hash); + if (cancelled_order_hash.is_some()) { + let cancelled_order_hash = cancelled_order_hash.unwrap(); + self + .emit( + OrderCancelled { + order_hash: cancelled_order_hash, + reason: OrderStatus::CancelledByNewOrder.into(), + order_type, + version: ORDER_CANCELLED_EVENT_VERSION, + } + ) + } self .emit( OrderPlaced { order_hash: order_hash, order_version: order.get_version(), order_type: order_type, + version: ORDER_PLACED_EVENT_VERSION, cancelled_order_hash, order: order } @@ -790,7 +664,10 @@ mod orderbook { /// Creates an auction order. fn _create_auction( - ref self: ContractState, order: OrderV1, order_type: OrderType, order_hash: felt252 + ref self: ComponentState, + order: OrderV1, + order_type: OrderType, + order_hash: felt252 ) { let token_hash = order.compute_token_hash(); let current_order_hash = self.token_listings.read(token_hash); @@ -815,26 +692,42 @@ mod orderbook { let cancelled_order_hash = self._process_previous_order(token_hash, order.offerer); order_write(order_hash, order_type, order); self.auctions.write(token_hash, (order_hash, order.end_date, 0)); + if (cancelled_order_hash.is_some()) { + let cancelled_order_hash = cancelled_order_hash.unwrap(); + self + .emit( + OrderCancelled { + order_hash: cancelled_order_hash, + reason: OrderStatus::CancelledByNewOrder.into(), + order_type, + version: ORDER_CANCELLED_EVENT_VERSION, + } + ) + } self .emit( OrderPlaced { order_hash: order_hash, order_version: order.get_version(), order_type: order_type, + version: ORDER_PLACED_EVENT_VERSION, cancelled_order_hash, order: order, } ); } - fn _manage_auction_offer(ref self: ContractState, order: OrderV1, order_hash: felt252) { + fn _manage_auction_offer( + ref self: ComponentState, order: OrderV1, order_hash: felt252 + ) { let token_hash = order.compute_token_hash(); let (auction_order_hash, auction_end_date, auction_offer_count) = self .auctions .read(token_hash); let current_block_timestamp = starknet::get_block_timestamp(); - // Determine if the auction end date has passed, indicating that the auction is still ongoing. + // Determine if the auction end date has passed, indicating that the auction is still + // ongoing. let auction_is_pending = current_block_timestamp < auction_end_date; if auction_is_pending { @@ -868,7 +761,10 @@ mod orderbook { /// Creates an offer order. fn _create_offer( - ref self: ContractState, order: OrderV1, order_type: OrderType, order_hash: felt252 + ref self: ComponentState, + order: OrderV1, + order_type: OrderType, + order_hash: felt252 ) { self._manage_auction_offer(order, order_hash); order_write(order_hash, order_type, order); @@ -878,6 +774,7 @@ mod orderbook { order_hash: order_hash, order_version: order.get_version(), order_type: order_type, + version: ORDER_PLACED_EVENT_VERSION, cancelled_order_hash: Option::None, order: order, } @@ -886,7 +783,10 @@ mod orderbook { /// Creates a collection offer order. fn _create_collection_offer( - ref self: ContractState, order: OrderV1, order_type: OrderType, order_hash: felt252 + ref self: ComponentState, + order: OrderV1, + order_type: OrderType, + order_hash: felt252 ) { order_write(order_hash, order_type, order); self @@ -894,7 +794,8 @@ mod orderbook { OrderPlaced { order_hash: order_hash, order_version: order.get_version(), - order_type: order_type, + order_type, + version: ORDER_PLACED_EVENT_VERSION, cancelled_order_hash: Option::None, order: order, } @@ -902,3 +803,15 @@ mod orderbook { } } } +pub impl OrderbookHooksCreateOrderEmptyImpl< + TContractState +> of OrderbookComponent::OrderbookHooksCreateOrderTrait {} +pub impl OrderbookHooksCancelOrderEmptyImpl< + TContractState +> of OrderbookComponent::OrderbookHooksCancelOrderTrait {} +pub impl OrderbookHooksFulfillOrderEmptyImpl< + TContractState +> of OrderbookComponent::OrderbookHooksFulfillOrderTrait {} +pub impl OrderbookHooksValidateOrderExecutionEmptyImpl< + TContractState +> of OrderbookComponent::OrderbookHooksValidateOrderExecutionTrait {} diff --git a/contracts/ark_orderbook/README.md b/contracts/ark_orderbook/README.md deleted file mode 100644 index 301866680..000000000 --- a/contracts/ark_orderbook/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Arkchain contracts - -This is mainly the orderbook contract with related order data. - -`asdf` version manangement is used, so you should have `scarb 0.7.0` installed. - -# Build - -To build: - -`scarb build` - -# Testing - -For testing, you must have [starknet forge](https://foundry-rs.github.io/starknet-foundry/getting-started/installation.html) installed (at least `0.9.1`). Then you can run: - -`snforge` diff --git a/contracts/ark_orderbook/Scarb.lock b/contracts/ark_orderbook/Scarb.lock deleted file mode 100644 index 9397aced5..000000000 --- a/contracts/ark_orderbook/Scarb.lock +++ /dev/null @@ -1,28 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "ark_common" -version = "0.1.0" -dependencies = [ - "openzeppelin", - "snforge_std", -] - -[[package]] -name = "arkchain" -version = "0.1.0" -dependencies = [ - "ark_common", - "snforge_std", -] - -[[package]] -name = "openzeppelin" -version = "0.8.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.8.0#c23e8e96de60e6e3159b1ff8591a1187269c0eb7" - -[[package]] -name = "snforge_std" -version = "0.1.0" -source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.9.1#da085bd11e1b151d0592f43917136560d9b70d37" diff --git a/contracts/ark_orderbook/Scarb.toml b/contracts/ark_orderbook/Scarb.toml deleted file mode 100644 index bfa59fd0d..000000000 --- a/contracts/ark_orderbook/Scarb.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "ark_orderbook" -version = "0.1.0" - -[dependencies] -ark_common = { path = "../ark_common" } -starknet = "2.5.4" -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.18.0" } - -[scripts] -test.workspace = true - -[[target.starknet-contract]] -sierra = true -casm = true diff --git a/contracts/ark_orderbook/src/lib.cairo b/contracts/ark_orderbook/src/lib.cairo deleted file mode 100644 index cf713305b..000000000 --- a/contracts/ark_orderbook/src/lib.cairo +++ /dev/null @@ -1,2 +0,0 @@ -mod orderbook; -mod orderbook_event_mock; diff --git a/contracts/ark_orderbook/src/orderbook_event_mock.cairo b/contracts/ark_orderbook/src/orderbook_event_mock.cairo deleted file mode 100644 index 1e94d05ba..000000000 --- a/contracts/ark_orderbook/src/orderbook_event_mock.cairo +++ /dev/null @@ -1,197 +0,0 @@ -//! # Orderbook event mock Contract -//! -//! A very simple orderbook like contract that is only used -//! to emit events in order to test the indexer. -//! This contract will no longer be used once the SDK is operational. -#[starknet::contract] -mod orderbook_event_mock { - use ark_common::protocol::order_types::{ - FulfillInfo, OrderType, CancelInfo, OrderStatus, RouteType - }; - use core::traits::TryInto; - use core::result::ResultTrait; - use core::zeroable::Zeroable; - use core::option::OptionTrait; - use core::starknet::event::EventEmitter; - use core::traits::Into; - use starknet::ContractAddress; - use ark_common::protocol::order_v1::OrderV1; - - #[storage] - struct Storage {} - - /// Events emitted by the Orderbook contract. - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - OrderPlaced: OrderPlaced, - OrderExecuted: OrderExecuted, - OrderCancelled: OrderCancelled, - RollbackStatus: RollbackStatus, - OrderFulfilled: OrderFulfilled, - } - - /// Event for when an order is placed. - #[derive(Drop, starknet::Event)] - struct OrderPlaced { - #[key] - order_hash: felt252, - #[key] - order_version: felt252, - #[key] - order_type: OrderType, - // The order that was cancelled by this order. - cancelled_order_hash: Option, - // The full order serialized. - order: OrderV1, - } - - /// Event for when an order is executed. - #[derive(Drop, starknet::Event)] - struct OrderExecuted { - #[key] - order_hash: felt252, - } - - /// Event for when an order is executed. - #[derive(Drop, starknet::Event)] - struct RollbackStatus { - #[key] - order_hash: felt252, - #[key] - reason: felt252, - } - - /// Event for when an order is cancelled. - #[derive(Drop, starknet::Event)] - struct OrderCancelled { - #[key] - order_hash: felt252, - #[key] - reason: felt252, - } - - /// Event for when an order is fulfilled. - #[derive(Drop, starknet::Event)] - struct OrderFulfilled { - #[key] - order_hash: felt252, - #[key] - fulfiller: ContractAddress, - #[key] - related_order_hash: Option, - } - - - #[abi(embed_v0)] - fn emit_order_fulfilled(ref self: ContractState) { - self - .emit( - OrderFulfilled { - order_hash: 0x1, - fulfiller: 0x123.try_into().unwrap(), - related_order_hash: Option::Some(0x1111), - } - ); - } - - #[abi(embed_v0)] - fn emit_order_placed(ref self: ContractState) { - self - .emit( - OrderPlaced { - order_hash: 0x1234, - order_version: 0x1, - order_type: OrderType::Listing, - cancelled_order_hash: Option::None, - order: OrderV1 { - route: RouteType::Erc721ToErc20, - currency_address: 0x1.try_into().unwrap(), - currency_chain_id: 'chain', - salt: 0x0, - offerer: 0x2.try_into().unwrap(), - token_chain_id: 'chain', - token_address: 0x3.try_into().unwrap(), - token_id: Option::Some(1), - quantity: 2, - start_amount: 3, - end_amount: 4, - start_date: 5, - end_date: 6, - broker_id: 0x2.try_into().unwrap(), - additional_data: array![].span(), - } - } - ); - } - - #[abi(embed_v0)] - fn emit_order_listing(ref self: ContractState) { - self - .emit( - OrderPlaced { - order_hash: 0x12345, - order_version: 0x1, - order_type: OrderType::Listing, - cancelled_order_hash: Option::None, - order: OrderV1 { - route: RouteType::Erc721ToErc20, - currency_address: 0x1.try_into().unwrap(), - currency_chain_id: 'chain', - salt: 0x0, - offerer: 0x2.try_into().unwrap(), - token_chain_id: 'chain', - token_address: 0x3.try_into().unwrap(), - token_id: Option::Some(1), - quantity: 1, - start_amount: 3, - end_amount: 4, - start_date: 5, - end_date: 6, - broker_id: 0x2.try_into().unwrap(), - additional_data: array![].span(), - } - } - ); - } - - #[abi(embed_v0)] - fn emit_order_offer_placed(ref self: ContractState) { - self - .emit( - OrderPlaced { - order_hash: 0x12346, - order_version: 0x1, - order_type: OrderType::Offer, - cancelled_order_hash: Option::None, - order: OrderV1 { - route: RouteType::Erc721ToErc20, - currency_address: 0x1.try_into().unwrap(), - currency_chain_id: 'chain', - salt: 0x0, - offerer: 0x3.try_into().unwrap(), - token_chain_id: 'chain', - token_address: 0x3.try_into().unwrap(), - token_id: Option::Some(1), - quantity: 2, - start_amount: 4, - end_amount: 0, - start_date: 2, - end_date: 0, - broker_id: 0x2.try_into().unwrap(), - additional_data: array![].span(), - } - } - ); - } - - #[abi(embed_v0)] - fn emit_order_offer_executed(ref self: ContractState) { - self.emit(OrderExecuted { order_hash: 0x12346, }); - } - - #[abi(embed_v0)] - fn emit_order_cancelled(ref self: ContractState) { - self.emit(OrderCancelled { order_hash: 0x1234, reason: 'fail', }); - } -} diff --git a/contracts/ark_orderbook/tests/common/setup.cairo b/contracts/ark_orderbook/tests/common/setup.cairo deleted file mode 100644 index 27349582a..000000000 --- a/contracts/ark_orderbook/tests/common/setup.cairo +++ /dev/null @@ -1,197 +0,0 @@ -use core::traits::TryInto; -use core::option::OptionTrait; -use core::traits::Into; -use ark_common::protocol::order_types::{RouteType, FulfillInfo, OrderTrait, OrderType, OrderStatus}; -use ark_common::crypto::signer::{Signer, SignInfo}; -use ark_common::protocol::order_v1::OrderV1; -use ark_orderbook::orderbook::{OrderbookDispatcher, OrderbookDispatcherTrait}; - -use snforge_std::signature::KeyPairTrait; -use snforge_std::signature::stark_curve::{ - StarkCurveKeyPairImpl, StarkCurveSignerImpl, StarkCurveVerifierImpl -}; - -use snforge_std::{start_prank, stop_prank, test_address, CheatTarget}; -use starknet::ContractAddress; - -/// Utility function to setup orders for test environment. -/// -/// # Returns a tuple of the different orders -/// * order_listing - A listing order of type OrderV1 -/// * order_offer - An offer order of type OrderV1 -/// * order_auction - An auction order of type OrderV1 -/// * order_collection_offer - An offer order of type OrderV1 for a collection -/// - -fn setup_orders() -> (OrderV1, OrderV1, OrderV1, OrderV1,) { - let data = array![]; - let data_span = data.span(); - let chain_id = 0x534e5f4d41494e; - - let order_listing = OrderV1 { - route: RouteType::Erc721ToErc20.into(), - currency_address: 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 - .try_into() - .unwrap(), - currency_chain_id: chain_id, - salt: 1, - offerer: 0x2284a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a81b - .try_into() - .unwrap(), - token_chain_id: chain_id, - token_address: 0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672 - .try_into() - .unwrap(), - token_id: Option::Some(10), - quantity: 1, - start_amount: 600000000000000000, - end_amount: 0, - start_date: starknet::get_block_timestamp(), - end_date: starknet::get_block_timestamp() + (30 * 24 * 60 * 60), - broker_id: 0x123.try_into().unwrap(), - additional_data: data_span, - }; - let order_offer = OrderV1 { - route: RouteType::Erc20ToErc721.into(), - currency_address: 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 - .try_into() - .unwrap(), - currency_chain_id: chain_id, - salt: 1, - offerer: 0x2284a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a81b - .try_into() - .unwrap(), - token_chain_id: chain_id, - token_address: 0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672 - .try_into() - .unwrap(), - token_id: Option::Some(10), - quantity: 1, - start_amount: 600000000000000000, - end_amount: 0, - start_date: 1699525884797, - end_date: 1702117884797, - broker_id: 0x123.try_into().unwrap(), - additional_data: data_span, - }; - let order_auction = OrderV1 { - route: RouteType::Erc721ToErc20.into(), - currency_address: 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 - .try_into() - .unwrap(), - currency_chain_id: chain_id, - salt: 0, - offerer: 0x2284a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a81b - .try_into() - .unwrap(), - token_chain_id: chain_id, - token_address: 0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672 - .try_into() - .unwrap(), - token_id: Option::Some(10), - quantity: 1, - start_amount: 600000000000000000, - end_amount: 600000000000000000, - start_date: starknet::get_block_timestamp(), - end_date: starknet::get_block_timestamp() + (30 * 24 * 60 * 60), - broker_id: 0x123.try_into().unwrap(), - additional_data: data_span, - }; - - let order_collection_offer = OrderV1 { - route: RouteType::Erc20ToErc721.into(), - currency_address: 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 - .try_into() - .unwrap(), - currency_chain_id: chain_id, - salt: 0, - offerer: 0x2284a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a81b - .try_into() - .unwrap(), - token_chain_id: chain_id, - token_address: 0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672 - .try_into() - .unwrap(), - token_id: Option::None, - quantity: 1, - start_amount: 600000000000000000, - end_amount: 0, - start_date: starknet::get_block_timestamp(), - end_date: starknet::get_block_timestamp() + (30 * 24 * 60 * 60), - broker_id: 0x123.try_into().unwrap(), - additional_data: data_span, - }; - - (order_listing, order_offer, order_auction, order_collection_offer) -} - -/// Utility function to setup a listing order for test environment. -/// -/// # Arguments -/// * `price` - The price of the listing -/// -/// # Returns a tuple of the different orders details -/// -fn setup_listing_order(price: felt252) -> (OrderV1, felt252, felt252) { - let block_timestamp = starknet::get_block_timestamp(); - let end_date = block_timestamp + (30 * 24 * 60 * 60); - let data = array![]; - let data_span = data.span(); - let chain_id = 0x534e5f4d41494e; - let order_listing = OrderV1 { - route: RouteType::Erc721ToErc20.into(), - currency_address: 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 - .try_into() - .unwrap(), - currency_chain_id: chain_id, - salt: 1, - offerer: 0x2284a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a81b - .try_into() - .unwrap(), - token_chain_id: chain_id, - token_address: 0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672 - .try_into() - .unwrap(), - token_id: Option::Some(10), - quantity: 1, - start_amount: price.into(), - end_amount: 0, - start_date: block_timestamp, - end_date: end_date, - broker_id: 0x123.try_into().unwrap(), - additional_data: data_span, - }; - let order_hash = order_listing.compute_order_hash(); - let token_hash = order_listing.compute_token_hash(); - (order_listing, order_hash, token_hash) -} - - -fn get_offer_order() -> OrderV1 { - let data = array![]; - let data_span = data.span(); - let chain_id = 0x534e5f4d41494e; - OrderV1 { - route: RouteType::Erc20ToErc721.into(), - currency_address: 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 - .try_into() - .unwrap(), - currency_chain_id: chain_id, - salt: 0, - offerer: 0x2284a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a81b - .try_into() - .unwrap(), - token_chain_id: chain_id, - token_address: 0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672 - .try_into() - .unwrap(), - token_id: Option::Some(1), - quantity: 1, - start_amount: 600000000000000000, - end_amount: 0, - start_date: starknet::get_block_timestamp(), - end_date: starknet::get_block_timestamp() + (30 * 24 * 60 * 60), - broker_id: test_address(), - additional_data: data_span, - } -} diff --git a/contracts/ark_orderbook/tests/lib.cairo b/contracts/ark_orderbook/tests/lib.cairo deleted file mode 100644 index 411f07586..000000000 --- a/contracts/ark_orderbook/tests/lib.cairo +++ /dev/null @@ -1,10 +0,0 @@ -mod common { - mod setup; -} - -mod unit { - mod order { - mod test_order_v1; - } - mod test_orderbook; -} diff --git a/contracts/ark_orderbook/tests/unit/order/test_order_v1.cairo b/contracts/ark_orderbook/tests/unit/order/test_order_v1.cairo deleted file mode 100644 index 479bb8221..000000000 --- a/contracts/ark_orderbook/tests/unit/order/test_order_v1.cairo +++ /dev/null @@ -1,125 +0,0 @@ -use core::option::OptionTrait; -use core::result::ResultTrait; -use core::traits::Into; -use core::traits::TryInto; -use ark_common::protocol::order_v1::{OrderV1, OrderTraitOrderV1}; -use ark_orderbook::orderbook::{ - orderbook, orderbook_errors, OrderbookDispatcher, OrderbookDispatcherTrait -}; -use ark_common::protocol::order_types::{OrderType, OrderTrait, RouteType}; -use ark_common::crypto::signer::{SignInfo, Signer, SignerValidator}; -use debug::PrintTrait; -use super::super::super::common::setup::setup_orders; -use snforge_std::{ContractClassTrait, declare}; - -// ********************************************************* -// validate_common_data -// ********************************************************* - -#[test] -fn test_validate_common_data_with_valid_order() { - let (order_listing, _, _, _) = setup_orders(); - - let result = order_listing.validate_common_data(starknet::get_block_timestamp()); - assert(result.is_ok(), 'Invalid result'); -} - -#[test] -fn should_returns_invalid_order_with_zero_quantity() { - let (order_listing, _, _, _) = setup_orders(); - let block_timestmap: u64 = 1699556828; - - let mut invalid_order = order_listing.clone(); - invalid_order.quantity = 0; - let result = invalid_order.validate_common_data(block_timestmap); - assert(!result.is_ok(), 'zero quantity'); -} - -#[test] -fn should_returns_invalid_order_with_zero_salt() { - let (order_listing, _, _, _) = setup_orders(); - - let mut invalid_order = order_listing.clone(); - invalid_order.salt = 0; - let result = invalid_order.validate_common_data(starknet::get_block_timestamp()); - assert(!result.is_ok(), 'zero salt'); -} - -#[test] -fn should_returns_invalid_order_with_no_token_id() { - let (order_listing, _, _, _) = setup_orders(); - - let mut invalid_order = order_listing.clone(); - invalid_order.token_id = Option::None; - assert(invalid_order.token_id.is_none(), 'token_id should be none'); - let result = invalid_order.validate_common_data(starknet::get_block_timestamp()); - assert(result.is_ok(), 'Result should be valid'); -} - -#[test] -fn should_returns_invalid_order_with_invalid_token_address() { - let (order_listing, _, _, _) = setup_orders(); - - let mut invalid_order = order_listing.clone(); - invalid_order.token_address = 0.try_into().unwrap(); - let result = invalid_order.validate_common_data(starknet::get_block_timestamp()); - assert(!result.is_ok(), 'invalid token address'); -} - -#[test] -fn should_returns_invalid_order_with_invalid_dates() { - let (order_listing, _, _, _) = setup_orders(); - let block_timestamp: u64 = starknet::get_block_timestamp(); - - let mut invalid_order = order_listing.clone(); - invalid_order.end_date = 0; - let result = invalid_order.validate_common_data(1); - assert(!result.is_ok(), 'zero end date'); - - let mut invalid_order = order_listing.clone(); - let result = invalid_order.validate_common_data(1699643230); - assert(!result.is_ok(), 'past start date'); - - let mut invalid_order = order_listing.clone(); - invalid_order.end_date = 1731225255; - let result = invalid_order.validate_common_data(block_timestamp); - assert(!result.is_ok(), 'end date too far'); -} - -#[test] -fn test_validate_order_listing() { - let (order_listing, _, _, _) = setup_orders(); - let validated_order = order_listing.validate_order_type(); - // test for order type detection validity - assert(validated_order.is_ok(), 'Fail to validate order type'); - assert(validated_order.unwrap() == OrderType::Listing, 'Fail for type listing'); -} - -#[test] -fn test_validate_order_offer() { - let (_, order_offer, _, _) = setup_orders(); - let validated_order = order_offer.validate_order_type(); - // test for order type detection validity - assert(validated_order.is_ok(), 'Fail to validate order type'); - assert(validated_order.unwrap() == OrderType::Offer, 'Fail for type offer'); -} - -#[test] -fn test_validate_order_auction() { - let (_, _, order_auction, _) = setup_orders(); - let validated_order = order_auction.validate_order_type(); - // test for order type detection validity - assert(validated_order.is_ok(), 'Fail to validate order type'); - assert(validated_order.unwrap() == OrderType::Auction, 'Fail for type auction'); -} - -#[test] -fn test_validate_order_collection_offer() { - let (_, _, _, order_collection_offer) = setup_orders(); - let validated_order = order_collection_offer.validate_order_type(); - // test for order type detection validity - assert(validated_order.is_ok(), 'Fail to validate order type'); - assert( - validated_order.unwrap() == OrderType::CollectionOffer, 'Fail for type collection offer' - ); -} diff --git a/contracts/ark_orderbook/tests/unit/test_orderbook.cairo b/contracts/ark_orderbook/tests/unit/test_orderbook.cairo index 19c5c4918..e69de29bb 100644 --- a/contracts/ark_orderbook/tests/unit/test_orderbook.cairo +++ b/contracts/ark_orderbook/tests/unit/test_orderbook.cairo @@ -1,446 +0,0 @@ -use core::option::OptionTrait; -use ark_orderbook::orderbook::{orderbook, orderbook_errors}; -use ark_common::protocol::order_v1::OrderV1; -use core::traits::Into; -use core::traits::TryInto; -use snforge_std::cheatcodes::CheatTarget; -use ark_common::crypto::signer::{SignInfo, Signer, SignerValidator}; -use ark_common::protocol::order_types::{OrderTrait, RouteType, OrderType, FulfillInfo, OrderStatus}; -use ark_common::protocol::order_database::{ - order_read, order_status_read, order_status_write, order_type_read -}; -use snforge_std::{ - start_warp, declare, ContractClassTrait, spy_events, EventSpy, EventFetcher, EventAssertions, - Event, SpyOn, test_address -}; -use array::ArrayTrait; - -use super::super::common::setup::{setup_listing_order, get_offer_order, setup_orders}; - -const ORDER_VERSION_V1: felt252 = 'v1'; - -#[test] -fn test_create_listing() { - let (order_listing_1, order_hash_1, _) = setup_listing_order(600000000000000000); - let contract_address = test_address(); - let mut state = orderbook::contract_state_for_testing(); - let mut spy = spy_events(SpyOn::One(contract_address)); - - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_1, OrderType::Listing, order_hash_1 - ); - - let order_option = order_read::(order_hash_1); - let order_status = order_status_read(order_hash_1); - let order_type = order_type_read(order_hash_1); - assert(order_option.is_some(), 'storage order'); - let order = order_option.unwrap(); - assert(order_status.is_some(), 'storage order'); - assert(order_status.unwrap() == OrderStatus::Open, 'order status'); - assert(order_type.is_some(), 'storage order'); - assert(order_type.unwrap() == OrderType::Listing, 'order type'); - assert(order.token_address == order_listing_1.token_address, 'token address does not match'); - // test price - assert(order.start_amount == order_listing_1.start_amount, 'price does not match'); - // test price start amount with value - assert(order.start_amount == 600000000000000000.into(), 'price does not match'); - // assert the order hash is associated in the storage to the ressource hash - let order_hash = order.compute_order_hash(); - let token_hash = order.compute_token_hash(); - let state_order_hash_for_token_hash = - orderbook::InternalFunctions::_get_order_hash_from_token_hash( - @state, token_hash - ); - assert(state_order_hash_for_token_hash == order_hash, 'storage order'); - spy - .assert_emitted( - @array![ - ( - contract_address, - orderbook::Event::OrderPlaced( - orderbook::OrderPlaced { - order_hash: order_hash_1, - cancelled_order_hash: Option::None, - order_version: ORDER_VERSION_V1, - order_type: OrderType::Listing, - order: order_listing_1 - } - ) - ) - ] - ); -} - -#[should_panic(expected: ('OB: order already exists',))] -#[test] -fn test_recreate_listing_same_owner() { - let (order_listing_1, order_hash_1, _) = setup_listing_order(600000000000000000); - let mut state = orderbook::contract_state_for_testing(); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_1, OrderType::Listing, order_hash_1 - ); - // check is first order is fulfilled - let order_status = order_status_read(order_hash_1).unwrap(); - assert(order_status == OrderStatus::Open, 'OB: order already exists'); - // create a second order over the first one same ressource hash different price - let (order_listing_2, order_hash_2, _) = setup_listing_order(500000000000000000); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_2, OrderType::Listing, order_hash_2 - ); -} - -#[should_panic(expected: ('OB: order fulfilled',))] -#[test] -fn test_recreate_listing_different_offerer_fulfilled() { - let (order_listing_1, order_hash_1, _) = setup_listing_order(600000000000000000); - let mut state = orderbook::contract_state_for_testing(); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_1, OrderType::Listing, order_hash_1 - ); - // fullfill the order 1 - order_status_write(order_hash_1, OrderStatus::Fulfilled); - // check is first order is fulfilled - - // assert(order_status.unwrap() == OrderStatus::Fulfilled, 'Order not fulfilled'); - // create a second order over the first one same ressource hash different price, different owner but the previous order is only fulfilled, to cover the case of user who just bought a token to list it instantly but the order is not yet executed - // we cannot place & cancel a previous order if it's fulfilled - let (mut order_listing_2, order_hash_2, _) = setup_listing_order(500000000000000000); - order_listing_2 - .offerer = 0x2484a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a81b - .try_into() - .unwrap(); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_2, OrderType::Listing, order_hash_2 - ); -} - -#[should_panic(expected: ('OB: order fulfilled',))] -#[test] -fn test_recreate_listing_same_offerer_fulfilled() { - let (order_listing_1, order_hash_1, _) = setup_listing_order(600000000000000000); - - let mut state = orderbook::contract_state_for_testing(); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_1, OrderType::Listing, order_hash_1 - ); - // fullfill the order 1 - order_status_write(order_hash_1, OrderStatus::Fulfilled); - // check is first order is fulfilled - let order_status = order_status_read(order_hash_1); - assert(order_status.unwrap() == OrderStatus::Fulfilled, 'Order not fulfilled'); - // create a second order over the first one same ressource hash different price, different owner but the previous order is only fulfilled, to cover the case of user who just bought a token to list it instantly but the order is not yet executed - // we cannot place & cancel a previous order if it's fulfilled - let (mut order_listing_2, order_hash_2, _) = setup_listing_order(500000000000000000); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_2, OrderType::Listing, order_hash_2 - ); -} - -#[test] -fn test_recreate_listing_new_owner() { - let (order_listing_1, order_hash_1, _) = setup_listing_order(600000000000000000); - - let mut state = orderbook::contract_state_for_testing(); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_1, OrderType::Listing, order_hash_1 - ); - - // create a second order over the first one same ressource hash different price, different owner it should work and cancel the previous one - let (mut order_listing_2, order_hash_2, _) = setup_listing_order(500000000000000000); - order_listing_2 - .offerer = 0x2584a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a823 - .try_into() - .unwrap(); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_2, OrderType::Listing, order_hash_2 - ); - - // assert order1 is cancelled - let order_option = order_read::(order_hash_1); - let order_status = order_status_read(order_hash_1); - assert(order_option.is_some(), 'storage order'); - assert(order_status.is_some(), 'storage order'); - assert(order_status.unwrap() == OrderStatus::CancelledByNewOrder, 'order status'); - - // assert order2 is open - let order_option = order_read::(order_hash_2); - let order_status = order_status_read(order_hash_2); - assert(order_option.is_some(), 'storage order'); - let order = order_option.unwrap(); - assert(order_status.is_some(), 'storage order'); - assert(order_status.unwrap() == OrderStatus::Open, 'order status'); - assert(order.token_address == order_listing_2.token_address, 'token address does not match'); -} - -#[test] -fn test_recreate_listing_same_owner_old_order_expired() { - let (mut order_listing_1, order_hash_1, _) = setup_listing_order(600000000000000000); - let mut state = orderbook::contract_state_for_testing(); - order_listing_1.end_date = starknet::get_block_timestamp(); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_1, OrderType::Listing, order_hash_1 - ); - // create a second order over the first one same ressource hash different price, different owner it should work and cancel the previous one - let (order_listing_2, order_hash_2, _) = setup_listing_order(500000000000000000); - - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_2, OrderType::Listing, order_hash_2 - ); - - // assert order1 is cancelled - let order_option = order_read::(order_hash_1); - let order_status = order_status_read(order_hash_1); - assert(order_option.is_some(), 'storage order'); - assert(order_status.is_some(), 'storage order'); - assert(order_status.unwrap() == OrderStatus::CancelledByNewOrder, 'order status'); - - // assert order2 is open - let order_option = order_read::(order_hash_2); - let order_status = order_status_read(order_hash_2); - assert(order_option.is_some(), 'storage order'); - let order = order_option.unwrap(); - assert(order_status.is_some(), 'storage order'); - assert(order_status.unwrap() == OrderStatus::Open, 'order status'); - assert(order.token_address == order_listing_2.token_address, 'token address does not match'); -} - -#[test] -fn test_create_offer() { - let offer_order = get_offer_order(); - let order_hash = '123'; - - let contract_address = test_address(); - let mut state = orderbook::contract_state_for_testing(); - let mut spy = spy_events(SpyOn::One(contract_address)); - - orderbook::InternalFunctions::_create_offer( - ref state, offer_order, OrderType::Offer, order_hash - ); - - let order_option = order_read::(order_hash); - assert(order_option.is_some(), 'storage order'); - let order = order_option.unwrap(); - assert(order.token_address == offer_order.token_address, 'token address does not match'); - - spy - .assert_emitted( - @array![ - ( - contract_address, - orderbook::Event::OrderPlaced( - orderbook::OrderPlaced { - order_hash, - order_version: ORDER_VERSION_V1, - order_type: OrderType::Offer, - order: offer_order, - cancelled_order_hash: Option::None - } - ) - ) - ] - ); -} - -#[test] -fn test_create_collection_offer() { - let contract_address = test_address(); - let mut spy = spy_events(SpyOn::One(contract_address)); - - let mut offer_order = get_offer_order(); - offer_order.token_id = Option::None; - let order_hash = '123'; - - let mut state = orderbook::contract_state_for_testing(); - orderbook::InternalFunctions::_create_collection_offer( - ref state, offer_order, OrderType::CollectionOffer, order_hash - ); - - let order_option = order_read::(order_hash); - assert(order_option.is_some(), 'storage order'); - let order = order_option.unwrap(); - assert(order.token_address == offer_order.token_address, 'token address does not match'); - - spy - .assert_emitted( - @array![ - ( - contract_address, - orderbook::Event::OrderPlaced( - orderbook::OrderPlaced { - order_hash, - order_version: ORDER_VERSION_V1, - order_type: OrderType::CollectionOffer, - order: offer_order, - cancelled_order_hash: Option::None - } - ) - ) - ] - ); -} - -#[test] -fn test_create_listing_order_and_fulfill_the_order() { - let (mut order_listing_1, order_hash_1, _) = setup_listing_order(600000000000000000); - let mut state = orderbook::contract_state_for_testing(); - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_1, OrderType::Listing, order_hash_1 - ); - - let fulfill_info = FulfillInfo { - order_hash: order_hash_1, - related_order_hash: Option::None, - fulfiller: 0x2584a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a81b - .try_into() - .unwrap(), - token_chain_id: order_listing_1.token_chain_id, - token_address: order_listing_1.token_address, - token_id: order_listing_1.token_id, - fulfill_broker_address: test_address() - }; - - // Try to fulfill the order - orderbook::InternalFunctions::_fulfill_listing_order(ref state, fulfill_info, order_listing_1,); - - // assert order1 is fulfilled - let order_option = order_read::(order_hash_1); - let order_status = order_status_read(order_hash_1); - assert(order_option.is_some(), 'storage order'); - assert(order_status.is_some(), 'storage order'); - assert(order_status.unwrap() == OrderStatus::Fulfilled, 'order status'); -} - -// another test trying to fulfill an expired order: should fail -#[should_panic(expected: ('OB: order expired',))] -#[test] -fn test_create_listing_order_and_fulfill_the_order_expired() { - let (mut order_listing_1, order_hash_1, _) = setup_listing_order(600000000000000000); - let mut state = orderbook::contract_state_for_testing(); - order_listing_1 - .end_date = - starknet::get_block_timestamp(); // we use the current block timestamp to make the order expired because if we substract it will be negative - let _ = orderbook::InternalFunctions::_create_listing_order( - ref state, order_listing_1, OrderType::Listing, order_hash_1 - ); - - let fulfill_info = FulfillInfo { - order_hash: order_hash_1, - related_order_hash: Option::None, - fulfiller: 0x2584a6517b487be8114013f277f9e2010ac001a24a93e3c48cdf5f8f345a81b - .try_into() - .unwrap(), - token_chain_id: order_listing_1.token_chain_id, - token_address: order_listing_1.token_address, - token_id: order_listing_1.token_id, - fulfill_broker_address: test_address() - }; - - // Try to fulfill the order - orderbook::InternalFunctions::_fulfill_listing_order(ref state, fulfill_info, order_listing_1,); -} - -#[test] -fn test_fulfill_classic_token_offer() { - let (order_listing, order_offer, _, _) = setup_orders(); - let contract_address = test_address(); - let fulfill_broker_address = test_address(); - let mut state = orderbook::contract_state_for_testing(); - - let mut spy = spy_events(SpyOn::One(contract_address)); - let order_hash = order_listing.compute_order_hash(); - - start_warp(CheatTarget::One(contract_address), order_listing.start_date); - - let fulfill_info = FulfillInfo { - order_hash, - related_order_hash: Option::Some(order_offer.compute_order_hash()), - fulfiller: order_listing.offerer, - token_chain_id: order_listing.token_chain_id, - token_address: order_listing.token_address, - token_id: order_listing.token_id, - fulfill_broker_address: fulfill_broker_address - }; - - orderbook::InternalFunctions::_fulfill_offer(ref state, fulfill_info, order_listing); - - spy - .assert_emitted( - @array![ - ( - contract_address, - orderbook::Event::OrderFulfilled( - orderbook::OrderFulfilled { - order_hash: fulfill_info.order_hash, - fulfiller: fulfill_info.fulfiller, - related_order_hash: Option::None - } - ) - ) - ] - ); -} - -#[test] -fn test_fulfill_classic_collection_offer() { - let (order_listing, mut order_offer, _, _) = setup_orders(); - let contract_address = test_address(); - let mut spy = spy_events(SpyOn::One(contract_address)); - let mut state = orderbook::contract_state_for_testing(); - - order_offer.token_id = Option::None; - order_offer.start_date = order_listing.start_date + 100; - order_offer.end_date = order_listing.start_date + 100; - - start_warp(CheatTarget::One(contract_address), order_offer.start_date); - - let fulfill_info = FulfillInfo { - order_hash: order_listing.compute_order_hash(), - related_order_hash: Option::Some(order_offer.compute_order_hash()), - fulfiller: order_listing.offerer, - token_chain_id: order_listing.token_chain_id, - token_address: order_listing.token_address, - token_id: Option::Some(1), - fulfill_broker_address: test_address() - }; - - orderbook::InternalFunctions::_fulfill_offer(ref state, fulfill_info, order_listing); - - spy - .assert_emitted( - @array![ - ( - contract_address, - orderbook::Event::OrderFulfilled( - orderbook::OrderFulfilled { - order_hash: fulfill_info.order_hash, - fulfiller: fulfill_info.fulfiller, - related_order_hash: Option::None - } - ) - ) - ] - ); -} - -#[test] -#[should_panic(expected: ('OB: order expired',))] -fn test_fulfill_expired_offer() { - let (order_listing, order_offer, _, _) = setup_orders(); - let contract_address = test_address(); - let fulfill_broker_address = test_address(); - let mut state = orderbook::contract_state_for_testing(); - - start_warp(CheatTarget::One(contract_address), order_listing.end_date + 3600); // +1 hour - - let fulfill_info = FulfillInfo { - order_hash: order_listing.compute_order_hash(), - related_order_hash: Option::Some(order_offer.compute_order_hash()), - fulfiller: order_listing.offerer, - token_chain_id: order_listing.token_chain_id, - token_address: order_listing.token_address, - token_id: order_listing.token_id, - fulfill_broker_address: fulfill_broker_address - }; - - orderbook::InternalFunctions::_fulfill_offer(ref state, fulfill_info, order_listing); -} diff --git a/contracts/ark_oz/Scarb.lock b/contracts/ark_oz/Scarb.lock index c3dc71dda..280f9f71c 100644 --- a/contracts/ark_oz/Scarb.lock +++ b/contracts/ark_oz/Scarb.lock @@ -11,10 +11,98 @@ dependencies = [ [[package]] name = "openzeppelin" -version = "0.10.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.10.0#d77082732daab2690ba50742ea41080eb23299d3" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_access", + "openzeppelin_account", + "openzeppelin_governance", + "openzeppelin_introspection", + "openzeppelin_presets", + "openzeppelin_security", + "openzeppelin_token", + "openzeppelin_upgrades", + "openzeppelin_utils", +] + +[[package]] +name = "openzeppelin_access" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_introspection", + "openzeppelin_utils", +] + +[[package]] +name = "openzeppelin_account" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_introspection", + "openzeppelin_utils", +] + +[[package]] +name = "openzeppelin_governance" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_access", + "openzeppelin_introspection", +] + +[[package]] +name = "openzeppelin_introspection" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" + +[[package]] +name = "openzeppelin_presets" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_access", + "openzeppelin_account", + "openzeppelin_introspection", + "openzeppelin_token", + "openzeppelin_upgrades", +] + +[[package]] +name = "openzeppelin_security" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" + +[[package]] +name = "openzeppelin_token" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" +dependencies = [ + "openzeppelin_account", + "openzeppelin_governance", + "openzeppelin_introspection", +] + +[[package]] +name = "openzeppelin_upgrades" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" + +[[package]] +name = "openzeppelin_utils" +version = "0.15.1" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.1#2f8a93d762858714095a1d391afffa9e21df6983" + +[[package]] +name = "snforge_scarb_plugin" +version = "0.1.0" +source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.28.0#4dfe39d96690ed6b3d56971512700de3f58288ea" [[package]] name = "snforge_std" -version = "0.18.0" -source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.18.0#48f909a56b08cbdc5ca6a21a836b0fbc6c36d55b" +version = "0.28.0" +source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.28.0#4dfe39d96690ed6b3d56971512700de3f58288ea" +dependencies = [ + "snforge_scarb_plugin", +] diff --git a/contracts/ark_oz/Scarb.toml b/contracts/ark_oz/Scarb.toml index ffa101978..9b73c8aef 100644 --- a/contracts/ark_oz/Scarb.toml +++ b/contracts/ark_oz/Scarb.toml @@ -5,9 +5,15 @@ version = "0.1.0" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -starknet = "2.5.4" -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.10.0" } -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.18.0" } +starknet = "2.7.1" +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.15.1" } + +[dev-dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.30.0" } +assert_macros = "0.1.0" + +[tool.fmt] +sort-module-level-items = true [lib] diff --git a/contracts/ark_oz/src/erc2981/erc2981.cairo b/contracts/ark_oz/src/erc2981/erc2981.cairo index 7b0c45b3f..b8eae00c6 100644 --- a/contracts/ark_oz/src/erc2981/erc2981.cairo +++ b/contracts/ark_oz/src/erc2981/erc2981.cairo @@ -1,6 +1,8 @@ #[starknet::component] pub mod ERC2981Component { use starknet::ContractAddress; + use starknet::storage::Map; + use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait; use openzeppelin::introspection::src5::SRC5Component::SRC5Impl; use openzeppelin::introspection::src5::SRC5Component; @@ -15,8 +17,8 @@ pub mod ERC2981Component { struct Storage { default_receiver: ContractAddress, default_fees: FeesRatio, - token_receiver: LegacyMap, - token_fees: LegacyMap, + token_receiver: Map, + token_fees: Map, } #[event] diff --git a/contracts/ark_oz/tests/test_erc2981.cairo b/contracts/ark_oz/tests/test_erc2981.cairo index eed401606..ab066b680 100644 --- a/contracts/ark_oz/tests/test_erc2981.cairo +++ b/contracts/ark_oz/tests/test_erc2981.cairo @@ -9,36 +9,31 @@ use ark_oz::erc2981::{IERC2981SetupDispatcher, IERC2981SetupDispatcherTrait}; use ark_oz::erc2981::{FeesRatio, FeesImpl, FeesRatioDefault}; -use snforge_std::{ContractClass, ContractClassTrait, declare}; -use snforge_std::{start_prank, stop_prank, CheatTarget}; +use snforge_std::{ContractClass, ContractClassTrait, declare, DeclareResultTrait, cheat_caller_address, CheatSpan}; fn setup_contract() -> (ContractAddress, ContractAddress, ContractAddress, FeesRatio) { let owner = contract_address_const::<'owner'>(); let receiver = contract_address_const::<'receiver'>(); let default_fees: FeesRatio = Default::default(); - let contract = declare('MockERC2981'); + let contract = declare("MockERC2981").unwrap().contract_class(); let mut calldata: Array = array![]; calldata.append(owner.into()); calldata.append(receiver.into()); default_fees.serialize(ref calldata); - - (contract.deploy(@calldata).unwrap(), owner, receiver, default_fees) + let (mock_erc2981_address, _) = contract.deploy(@calldata).unwrap(); + (mock_erc2981_address, owner, receiver, default_fees) } #[test] fn test_fees_ratio_invalid() { - assert!(!FeesRatio { numerator: 0, denominator: 0, }.is_valid(), "Shall be invalid"); - - assert!(!FeesRatio { numerator: 30, denominator: 30, }.is_valid(), "Shall be invalid"); - - assert!(!FeesRatio { numerator: 40, denominator: 30, }.is_valid(), "Shall be invalid"); - - assert!(!FeesRatio { numerator: 5, denominator: 10000, }.is_valid(), "Shall be invalid"); - - assert!(!FeesRatio { numerator: 0, denominator: 0 }.is_valid(), "Shall be invalid"); - - assert!(FeesRatio { numerator: 0, denominator: 1, }.is_valid(), "Shall be valid"); + assert!(!FeesRatio { numerator: 0, denominator: 0, }.is_valid(), "(0,0) Shall be invalid"); + assert!(!FeesRatio { numerator: 30, denominator: 30, }.is_valid(), "(30,30) Shall be invalid"); + assert!(!FeesRatio { numerator: 40, denominator: 30, }.is_valid(), "(40,30) Shall be invalid"); + assert!(FeesRatio { numerator: 5, denominator: 10000, }.is_valid(), "(5,10000) Shall be valid"); + assert!(!FeesRatio { numerator: 5, denominator: 10001, }.is_valid(), "(5,10001) Shall be invalid"); + assert!(!FeesRatio { numerator: 0, denominator: 0 }.is_valid(), "(0,0) Shall be invalid"); + assert!(FeesRatio { numerator: 0, denominator: 1, }.is_valid(), "(0,1) Shall be valid"); } #[test] @@ -59,15 +54,14 @@ fn test_erc2981_interface_is_supported() { } #[test] -#[should_panic(expected: ('Caller is not the owner',))] +#[should_panic(expected: 'Caller is not the owner')] fn test_only_owner_can_set_default_royalty() { let (contract_address, _, _, _) = setup_contract(); let alice = contract_address_const::<'alice'>(); let other_receiver = contract_address_const::<'other_receiver'>(); let token = IERC2981SetupDispatcher { contract_address: contract_address }; - start_prank(CheatTarget::One(contract_address), alice); + cheat_caller_address(contract_address, alice, CheatSpan::TargetCalls(1)); token.set_default_royalty(other_receiver, Default::default()); - stop_prank(CheatTarget::One(contract_address)); } // TODO: add event check @@ -77,9 +71,10 @@ fn test_owner_set_default_royalty() { let other_receiver = contract_address_const::<'other_receiver'>(); let other_fees = FeesRatio { numerator: 5, denominator: 100, }; let token = IERC2981SetupDispatcher { contract_address: contract_address }; - start_prank(CheatTarget::One(contract_address), owner); + + cheat_caller_address(contract_address, owner, CheatSpan::TargetCalls(1)); token.set_default_royalty(other_receiver, other_fees); - stop_prank(CheatTarget::One(contract_address)); + let (receiver, fees_ratio) = token.default_royalty(); assert_eq!(receiver, other_receiver, "Default receiver not updated"); assert_eq!(fees_ratio, other_fees, "Default fees not updated"); @@ -94,9 +89,8 @@ fn test_owner_set_token_royalty() { let other_fees = FeesRatio { numerator: 5, denominator: 100, }; let token = IERC2981SetupDispatcher { contract_address: contract_address }; - start_prank(CheatTarget::One(contract_address), owner); + cheat_caller_address(contract_address, owner, CheatSpan::TargetCalls(1)); token.set_token_royalty(token_id, other_receiver, other_fees); - stop_prank(CheatTarget::One(contract_address)); let (receiver, fees_ratio) = token.token_royalty(token_id); assert_eq!(receiver, other_receiver, "Token receiver not updated"); @@ -107,7 +101,7 @@ fn test_owner_set_token_royalty() { } #[test] -#[should_panic(expected: ('Caller is not the owner',))] +#[should_panic(expected: 'Caller is not the owner')] fn test_only_owner_can_set_token_royalty() { let token_id = 256; let alice = contract_address_const::<'alice'>(); @@ -116,9 +110,8 @@ fn test_only_owner_can_set_token_royalty() { let other_fees = FeesRatio { numerator: 5, denominator: 100, }; let token = IERC2981SetupDispatcher { contract_address: contract_address }; - start_prank(CheatTarget::One(contract_address), alice); + cheat_caller_address(contract_address, alice, CheatSpan::TargetCalls(1)); token.set_token_royalty(token_id, other_receiver, other_fees); - stop_prank(CheatTarget::One(contract_address)); } #[test] @@ -132,10 +125,9 @@ fn test_royalty_compute() { let other_receiver = contract_address_const::<'other_receiver'>(); let other_fees = FeesRatio { numerator: 5, denominator: 100 }; - start_prank(CheatTarget::One(contract_address), owner); + cheat_caller_address(contract_address, owner, CheatSpan::TargetCalls(2)); token.set_token_royalty(token_id, token_receiver, token_fees); token.set_default_royalty(other_receiver, other_fees); - stop_prank(CheatTarget::One(contract_address)); let sale_price = 100_000_000; let token = IERC2981Dispatcher { contract_address: contract_address }; diff --git a/contracts/ark_starknet/Scarb.toml b/contracts/ark_starknet/Scarb.toml index 7aa7af24b..b1b5436cb 100644 --- a/contracts/ark_starknet/Scarb.toml +++ b/contracts/ark_starknet/Scarb.toml @@ -3,16 +3,27 @@ name = "ark_starknet" version = "0.1.0" [dependencies] -starknet = "2.5.4" -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.10.0" } -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.18.0" } +starknet.workspace = true +openzeppelin.workspace = true ark_common = { path = "../ark_common" } +ark_component = { path = "../ark_component" } + +# Should be in dev-dependencies but scarb 2.7.1 complains: +# warn: external contracts not found for selectors: +# `ark_tokens::erc20::FreeMintERC20`, `ark_tokens::erc721::FreeMintNFT`, `ark_tokens::erc721_royalty::FreeMintNFTRoyalty` ark_tokens = { path = "../ark_tokens" } ark_oz = { path = "../ark_oz" } +[dev-dependencies] +snforge_std.workspace = true +assert_macros.workspace = true + [scripts] test.workspace = true +[tool] +fmt.workspace = true + [[target.starknet-contract]] sierra = true casm = true @@ -21,4 +32,5 @@ build-external-contracts = [ "ark_tokens::erc20::FreeMintERC20", "ark_tokens::erc721::FreeMintNFT", "ark_tokens::erc721_royalty::FreeMintNFTRoyalty", + "ark_tokens::erc1155::FreeMintERC1155", ] diff --git a/contracts/ark_starknet/src/appchain_messaging.cairo b/contracts/ark_starknet/src/appchain_messaging.cairo deleted file mode 100644 index 37a34eee5..000000000 --- a/contracts/ark_starknet/src/appchain_messaging.cairo +++ /dev/null @@ -1,359 +0,0 @@ -//! The messaging between an appchain and starknet -//! is done in a smiliar way starknet interacts with ethereum. -//! -//! This contract, deployed on starknet, will emit events. -//! The sequencer of the appchain (solis in our case) will -//! listen for those events. When an event with a message is gathered -//! by Solis, if the message is validated by Solis, -//! a L1 handler transaction is then created and added to the pool. -//! -//! For the appchain to send a message to starknet, the process can be done in two -//! fashions: -//! -//! 1. The appchain register messages hashes exactly as starknet does. And then -//! a transaction on starknet must be issued to consume the message. -//! -//! 2. The sequencer (Solis) has also the capability of directly send -//! a transaction to "execute" the content of the message. In the appchain -//! context this is a very effective manner to have a more dynamic and real-time -//! messaging than manual consuming of a message. -//! - -/// Trait for Appchain messaging. For now, the messaging only whitelist one -/// appchain. -#[starknet::interface] -trait IAppchainMessaging { - /// Update the account address (on starknet or any chain where this contract is - /// deployed) to accept messages. - /// - /// # Arguments - /// - /// * `appchain_address` - The address of the account contract of the appchain. - /// Only this account will be able to send transactions to this contract. - fn update_appchain_account_address(ref self: T, appchain_address: starknet::ContractAddress); - - /// Sends a message to an appchain by emitting an event. - /// Returns the message hash and the nonce. - /// - /// # Arguments - /// - /// * `to_address` - The appchain contract to send the message to. - /// * `selector` - The function selector to call on the appchain contract. - /// * `payload` - The message payload. - fn send_message_to_appchain( - ref self: T, - to_address: starknet::ContractAddress, - selector: felt252, - payload: Span, - ) -> (felt252, felt252); - - /// Registers messages hashes as consumable. - /// Usually, this function is only callable by the appchain developer/owner - /// that control the appchain sequencer. - /// All registered messages can then be consumed manually. - /// - /// # Arguments - /// - /// * `messages_hashes` - Hashes of the messages to be registered as consumable. - fn add_messages_hashes_from_appchain(ref self: T, messages_hashes: Span); - - /// Consumes a message registered as consumable by the appchain. - /// This is the traditional consuming as done on ethereum. - /// Returnes the message hash on success. - /// - /// # Arguments - /// - /// * `from_address` - The contract address recipient of the message. - /// * `payload` - The message payload. - fn consume_message_from_appchain( - ref self: T, from_address: starknet::ContractAddress, payload: Span, - ) -> felt252; - - /// Executes a message sent from the appchain. A message to execute - /// does not need to be registered as consumable. It is automatically - /// consumed while executed. - /// - /// # Arguments - /// - /// * `from_address` - The appchain contract that sent the message. - /// * `to_address` - The contract recipient of the message. - /// * `selector` - The function selector to call on recipient contract. - /// * `payload` - The message payload. - fn execute_message_from_appchain( - ref self: T, - from_address: starknet::ContractAddress, - to_address: starknet::ContractAddress, - selector: felt252, - payload: Span, - ); -} - -#[starknet::interface] -trait IUpgradeable { - fn upgrade(ref self: T, class_hash: starknet::ClassHash); -} - -#[starknet::contract] -mod appchain_messaging { - use starknet::{ContractAddress, ClassHash}; - use debug::PrintTrait; - - use super::{IAppchainMessaging, IUpgradeable}; - - #[storage] - struct Storage { - // Owner of this contract. - owner: ContractAddress, - // The account on Starknet (or the chain where this contract is deployed) - // used by the appchain sequencer to register messages hashes / execute messages. - appchain_account: ContractAddress, - // The nonce for messages sent from Starknet. - sn_to_appc_nonce: felt252, - // Ledger of messages hashes sent from Starknet to the appchain. - sn_to_appc_messages: LegacyMap::, - // Ledger of messages hashes registered from the appchain and a refcount - // associated to it. - appc_to_sn_messages: LegacyMap::, - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - MessageSentToAppchain: MessageSentToAppchain, - MessagesRegisteredFromAppchain: MessagesRegisteredFromAppchain, - MessageConsumed: MessageConsumed, - MessageExecuted: MessageExecuted, - Upgraded: Upgraded, - } - - #[derive(Drop, starknet::Event)] - struct MessageSentToAppchain { - #[key] - message_hash: felt252, - #[key] - from: ContractAddress, - #[key] - to: ContractAddress, - selector: felt252, - nonce: felt252, - payload: Span, - } - - #[derive(Drop, starknet::Event)] - struct MessagesRegisteredFromAppchain { - messages_hashes: Span, - } - - #[derive(Drop, starknet::Event)] - struct MessageConsumed { - #[key] - message_hash: felt252, - #[key] - from: ContractAddress, - #[key] - to: ContractAddress, - payload: Span, - } - - #[derive(Drop, starknet::Event)] - struct MessageExecuted { - #[key] - from_address: ContractAddress, - #[key] - to_address: ContractAddress, - #[key] - selector: felt252, - payload: Span, - } - - #[derive(Drop, starknet::Event)] - struct Upgraded { - class_hash: ClassHash, - } - - #[constructor] - fn constructor( - ref self: ContractState, owner: ContractAddress, appchain_account: ContractAddress, - ) { - self.owner.write(owner); - self.appchain_account.write(appchain_account); - } - - /// Computes the starknet keccak to have a hash that fits in one felt. - fn starknet_keccak(data: Span) -> felt252 { - let mut u256_data: Array = array![]; - - let mut i = 0_usize; - loop { - if i == data.len() { - break; - } - u256_data.append((*data[i]).into()); - i += 1; - }; - - let mut hash = keccak::keccak_u256s_be_inputs(u256_data.span()); - let low = integer::u128_byte_reverse(hash.high); - let high = integer::u128_byte_reverse(hash.low); - hash = u256 { low, high }; - hash = hash & 0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_u256; - hash.try_into().expect('starknet keccak overflow') - } - - /// Computes message hash to consume messages from appchain. - /// starknet_keccak(from_address, to_address, payload_len, payload). - fn compute_hash_appc_to_sn( - from_address: ContractAddress, to_address: ContractAddress, payload: Span - ) -> felt252 { - let mut hash_data: Array = array![ - from_address.into(), to_address.into(), payload.len().into(), - ]; - - let mut i = 0_usize; - loop { - if i == payload.len() { - break; - } - hash_data.append((*payload[i])); - i += 1; - }; - - starknet_keccak(hash_data.span()) - } - - /// Computes message hash to send messages to appchain. - /// starknet_keccak(nonce, to_address, selector, payload). - fn compute_hash_sn_to_appc( - nonce: felt252, to_address: ContractAddress, selector: felt252, payload: Span - ) -> felt252 { - let mut hash_data = array![nonce, to_address.into(), selector,]; - - let mut i = 0_usize; - loop { - if i == payload.len() { - break; - } - hash_data.append((*payload[i])); - i += 1; - }; - - starknet_keccak(hash_data.span()) - } - - #[abi(embed_v0)] - impl AppchainMessagingUpgradeImpl of IUpgradeable { - fn upgrade(ref self: ContractState, class_hash: ClassHash) { - assert( - starknet::get_caller_address() == self.owner.read(), 'Unauthorized replace class' - ); - - match starknet::replace_class_syscall(class_hash) { - Result::Ok(_) => self.emit(Upgraded { class_hash }), - Result::Err(revert_reason) => panic(revert_reason), - }; - } - } - - #[abi(embed_v0)] - impl AppchainMessagingImpl of IAppchainMessaging { - fn update_appchain_account_address( - ref self: ContractState, appchain_address: ContractAddress - ) { - assert(starknet::get_caller_address() == self.owner.read(), 'Unauthorized update'); - - self.appchain_account.write(appchain_address); - } - - fn send_message_to_appchain( - ref self: ContractState, - to_address: ContractAddress, - selector: felt252, - payload: Span - ) -> (felt252, felt252) { - let nonce = self.sn_to_appc_nonce.read() + 1; - self.sn_to_appc_nonce.write(nonce); - - let msg_hash = compute_hash_sn_to_appc(nonce, to_address, selector, payload); - - self - .emit( - MessageSentToAppchain { - message_hash: msg_hash, - from: starknet::get_caller_address(), - to: to_address, - selector, - nonce, - payload, - } - ); - - self.sn_to_appc_messages.write(msg_hash, nonce); - (msg_hash, nonce) - } - - fn add_messages_hashes_from_appchain( - ref self: ContractState, messages_hashes: Span - ) { - assert( - self.appchain_account.read() == starknet::get_caller_address(), - 'Unauthorized hashes registrar', - ); - - let mut i = 0_usize; - loop { - if i == messages_hashes.len() { - break; - } - - let msg_hash = *messages_hashes[i]; - - let count = self.appc_to_sn_messages.read(msg_hash); - self.appc_to_sn_messages.write(msg_hash, count + 1); - - i += 1; - }; - - self.emit(MessagesRegisteredFromAppchain { messages_hashes }); - } - - fn consume_message_from_appchain( - ref self: ContractState, from_address: ContractAddress, payload: Span - ) -> felt252 { - let to_address = starknet::get_caller_address(); - - let msg_hash = compute_hash_appc_to_sn(from_address, to_address, payload); - - let count = self.appc_to_sn_messages.read(msg_hash); - assert(count.is_non_zero(), 'INVALID_MESSAGE_TO_CONSUME'); - - self - .emit( - MessageConsumed { - message_hash: msg_hash, from: from_address, to: to_address, payload, - } - ); - - self.appc_to_sn_messages.write(msg_hash, count - 1); - - msg_hash - } - - fn execute_message_from_appchain( - ref self: ContractState, - from_address: ContractAddress, - to_address: ContractAddress, - selector: felt252, - payload: Span, - ) { - assert( - self.appchain_account.read() == starknet::get_caller_address(), - 'Unauthorized executor', - ); - match starknet::call_contract_syscall(to_address, selector, payload) { - Result::Ok(_) => self - .emit(MessageExecuted { from_address, to_address, selector, payload, }), - Result::Err(e) => { panic(e) } - } - } - } -} diff --git a/contracts/ark_starknet/src/executor.cairo b/contracts/ark_starknet/src/executor.cairo index dbb4f8659..e9572e7b9 100644 --- a/contracts/ark_starknet/src/executor.cairo +++ b/contracts/ark_starknet/src/executor.cairo @@ -1,13 +1,11 @@ use ark_common::protocol::order_types::OrderTrait; -use core::serde::Serde; +use ark_common::protocol::order_types::OrderType; -use starknet::ContractAddress; -use ark_common::protocol::order_v1::{OrderV1, OrderTraitOrderV1}; -use ark_common::protocol::order_types::OrderType; +use starknet::ContractAddress; -#[derive(Drop, Copy, Debug, Serde, starknet::Store)] +#[derive(Drop, Copy, Debug)] struct OrderInfo { order_type: OrderType, // Contract address of the currency used on Starknet for the transfer. @@ -17,113 +15,90 @@ struct OrderInfo { // The token id. // TODO: how to store Option ? token_id: u256, + // The quantity of the token (1 for ERC-721, variable for ERC-1155). + quantity: u256, // in wei. --> 10 | 10 | 10 | start_amount: u256, // offerer: ContractAddress, } - -impl OrderV1IntoOrderInfo of Into { - fn into(self: OrderV1) -> OrderInfo { - let order_type = self.validate_order_type().expect('Unsupported Order'); - let token_id = match self.token_id { - Option::Some(token_id) => token_id, - Option::None => 0, - }; - OrderInfo { - order_type, - currency_address: self.currency_address, - token_address: self.token_address, - token_id: token_id, - start_amount: self.start_amount, - offerer: self.offerer, - } - } -} -//! Executor contract on Starknet for arkchain. +//! Executor contract on Starknet //! //! This contract is responsible of executing the orders //! and move the assets accordingly. //! Once done, an event is emitted to confirm at the arkchain //! that the order was executed correctly. //! -//! In order to communicate with the Arkchain, this contract -//! uses the `appchain_messaging` contract dispatcher to send -//! messages. #[starknet::contract] mod executor { - use core::zeroable::Zeroable; - use core::traits::Into; - use starknet::contract_address_to_felt252; - use starknet::get_contract_address; - - use core::debug::PrintTrait; - use core::traits::TryInto; - use core::box::BoxTrait; - use core::option::OptionTrait; - - use starknet::{ContractAddress, ClassHash}; use ark_common::protocol::order_types::{ RouteType, ExecutionInfo, ExecutionValidationInfo, FulfillInfo, CreateOrderInfo, FulfillOrderInfo, CancelOrderInfo, CancelInfo, OrderType, }; use ark_common::protocol::order_v1::{OrderV1, OrderTraitOrderV1}; + use ark_component::orderbook::OrderbookComponent; + use ark_component::orderbook::{ + OrderbookHooksCreateOrderEmptyImpl, OrderbookHooksCancelOrderEmptyImpl, + OrderbookHooksFulfillOrderEmptyImpl, OrderbookHooksValidateOrderExecutionEmptyImpl, + }; use ark_oz::erc2981::interface::IERC2981_ID; - use ark_oz::erc2981::{IERC2981Dispatcher, IERC2981DispatcherTrait}; use ark_oz::erc2981::{FeesRatio, FeesRatioDefault, FeesImpl}; + use ark_oz::erc2981::{IERC2981Dispatcher, IERC2981DispatcherTrait}; - use ark_starknet::interfaces::{IExecutor, IUpgradable, IMaintenance}; use ark_starknet::interfaces::FeesAmount; - use ark_starknet::appchain_messaging::{ - IAppchainMessagingDispatcher, IAppchainMessagingDispatcherTrait, - }; + use ark_starknet::interfaces::{IExecutor, IUpgradable, IMaintenance}; + use core::box::BoxTrait; + + use core::debug::PrintTrait; + use core::option::OptionTrait; + use core::traits::Into; + use core::traits::TryInto; + use core::zeroable::Zeroable; + use openzeppelin::introspection::interface::{ISRC5, ISRC5Dispatcher, ISRC5DispatcherTrait}; use openzeppelin::token::{ - erc721::interface::{IERC721, IERC721Dispatcher, IERC721DispatcherTrait}, - erc20::interface::{IERC20, IERC20Dispatcher, IERC20DispatcherTrait} + erc721::interface::{IERC721, IERC721Dispatcher, IERC721DispatcherTrait, IERC721_ID}, + erc20::interface::{IERC20, IERC20Dispatcher, IERC20DispatcherTrait}, + erc1155::interface::{IERC1155, IERC1155Dispatcher, IERC1155DispatcherTrait, IERC1155_ID}, }; - use openzeppelin::introspection::interface::{ISRC5, ISRC5Dispatcher, ISRC5DispatcherTrait}; + use starknet::contract_address_to_felt252; + use starknet::get_contract_address; + use starknet::storage::Map; + + use starknet::{ContractAddress, ClassHash}; + + use super::OrderInfo; - use super::{OrderInfo, OrderV1IntoOrderInfo}; + component!(path: OrderbookComponent, storage: orderbook, event: OrderbookEvent); #[storage] struct Storage { admin_address: ContractAddress, - arkchain_orderbook_address: ContractAddress, eth_contract_address: ContractAddress, - messaging_address: ContractAddress, chain_id: felt252, - broker_fees: LegacyMap, + broker_fees: Map, ark_fees: FeesRatio, - // order hash -> OrderInfo - orders: LegacyMap, // fallback when collection doesn't implement ERC2981 default_receiver: ContractAddress, default_fees: FeesRatio, - creator_fees: LegacyMap, + creator_fees: Map, // maintenance mode in_maintenance: bool, + #[substorage(v0)] + orderbook: OrderbookComponent::Storage, } #[event] #[derive(Drop, starknet::Event)] enum Event { - OrderExecuted: OrderExecuted, CollectionFallbackFees: CollectionFallbackFees, ExecutorInMaintenance: ExecutorInMaintenance, - } - - #[derive(Drop, starknet::Event)] - struct OrderExecuted { - #[key] - order_hash: felt252, - #[key] - transaction_hash: felt252, - block_timestamp: u64 + #[flat] + OrderbookEvent: OrderbookComponent::Event, } #[derive(Drop, starknet::Event)] @@ -147,17 +122,19 @@ mod executor { const FEES_RATIO_INVALID: felt252 = 'Fees ratio is invalid'; } + #[abi(embed_v0)] + impl OrderbookImpl = OrderbookComponent::OrderbookImpl; + impl OrderbookActionImpl = OrderbookComponent::OrderbookActionImpl; + #[constructor] fn constructor( ref self: ContractState, admin_address: ContractAddress, eth_contract_address: ContractAddress, - messaging_address: ContractAddress, chain_id: felt252 ) { self.admin_address.write(admin_address); self.eth_contract_address.write(eth_contract_address); - self.messaging_address.write(messaging_address); self.chain_id.write(chain_id); self.ark_fees.write(Default::default()); self.default_receiver.write(admin_address); @@ -255,40 +232,12 @@ mod executor { } } - fn get_messaging_address(self: @ContractState) -> ContractAddress { - self.messaging_address.read() - } - - fn get_orderbook_address(self: @ContractState) -> ContractAddress { - self.arkchain_orderbook_address.read() - } - - fn update_arkchain_orderbook_address( - ref self: ContractState, orderbook_address: ContractAddress - ) { - _ensure_admin(@self); - - self.arkchain_orderbook_address.write(orderbook_address); - } - - fn update_messaging_address(ref self: ContractState, msger_address: ContractAddress) { - _ensure_admin(@self); - - self.messaging_address.write(msger_address); - } - fn update_eth_address(ref self: ContractState, eth_address: ContractAddress) { _ensure_admin(@self); self.eth_contract_address.write(eth_address); } - fn update_orderbook_address(ref self: ContractState, orderbook_address: ContractAddress) { - _ensure_admin(@self); - - self.arkchain_orderbook_address.write(orderbook_address); - } - fn update_admin_address(ref self: ContractState, admin_address: ContractAddress) { _ensure_admin(@self); @@ -297,199 +246,33 @@ mod executor { fn cancel_order(ref self: ContractState, cancelInfo: CancelInfo) { _ensure_is_not_in_maintenance(@self); - let messaging = IAppchainMessagingDispatcher { - contract_address: self.messaging_address.read() - }; let vinfo = CancelOrderInfo { cancelInfo: cancelInfo.clone() }; + _verify_cancel_order(@self, @vinfo); - let mut vinfo_buf = array![]; - Serde::serialize(@vinfo, ref vinfo_buf); - - messaging - .send_message_to_appchain( - self.arkchain_orderbook_address.read(), - selector!("cancel_order_from_l2"), - vinfo_buf.span(), - ); + self.orderbook.cancel_order(cancelInfo); } fn create_order(ref self: ContractState, order: OrderV1) { _ensure_is_not_in_maintenance(@self); - let messaging = IAppchainMessagingDispatcher { - contract_address: self.messaging_address.read() - }; let vinfo = CreateOrderInfo { order: order.clone() }; _verify_create_order(@self, @vinfo); - let order_hash = order.compute_order_hash(); - let order_info = order.into(); - self.orders.write(order_hash, order_info); - - let mut vinfo_buf = array![]; - Serde::serialize(@vinfo, ref vinfo_buf); - - messaging - .send_message_to_appchain( - self.arkchain_orderbook_address.read(), - selector!("create_order_from_l2"), - vinfo_buf.span(), - ); + self.orderbook.create_order(order); } fn fulfill_order(ref self: ContractState, fulfillInfo: FulfillInfo) { _ensure_is_not_in_maintenance(@self); - let messaging = IAppchainMessagingDispatcher { - contract_address: self.messaging_address.read() - }; let vinfo = FulfillOrderInfo { fulfillInfo: fulfillInfo.clone() }; _verify_fulfill_order(@self, @vinfo); - let mut vinfo_buf = array![]; - Serde::serialize(@vinfo, ref vinfo_buf); - - messaging - .send_message_to_appchain( - self.arkchain_orderbook_address.read(), - selector!("fulfill_order_from_l2"), - vinfo_buf.span(), - ); - } - - fn execute_order(ref self: ContractState, execution_info: ExecutionInfo) { - // assert( - // starknet::get_caller_address() == self.messaging_address.read(), - // 'Invalid msg sender' - // ); - - // Check if execution_info.currency_contract_address is whitelisted - _ensure_is_not_in_maintenance(@self); - assert( - execution_info.payment_currency_chain_id == self.chain_id.read(), - 'Chain ID is not SN_MAIN' - ); - - let currency_contract = IERC20Dispatcher { - contract_address: execution_info.payment_currency_address.try_into().unwrap() - }; - - let (creator_address, creator_fees_amount) = _compute_creator_fees_amount( - @self, - @execution_info.nft_address, - execution_info.payment_amount, - execution_info.nft_token_id - ); - let (fulfill_broker_fees_amount, listing_broker_fees_amount, ark_fees_amount, _) = - _compute_fees_amount( - @self, - execution_info.fulfill_broker_address, - execution_info.listing_broker_address, - execution_info.nft_address, - execution_info.nft_token_id, - execution_info.payment_amount - ); - assert!( - execution_info - .payment_amount > (fulfill_broker_fees_amount - + listing_broker_fees_amount - + creator_fees_amount - + ark_fees_amount), - "Fees exceed payment amount" - ); - - let seller_amount = execution_info.payment_amount - - (fulfill_broker_fees_amount - + listing_broker_fees_amount - + creator_fees_amount - + ark_fees_amount); - - // split the fees - currency_contract - .transfer_from( - execution_info.payment_from, - execution_info.fulfill_broker_address, - fulfill_broker_fees_amount, - ); - - currency_contract - .transfer_from( - execution_info.payment_from, - execution_info.listing_broker_address, - listing_broker_fees_amount - ); - - if creator_fees_amount > 0 { - let (default_receiver_creator, _) = self.get_default_creator_fees(); - if creator_address == default_receiver_creator { - self - .emit( - CollectionFallbackFees { - collection: execution_info.nft_address, - amount: creator_fees_amount, - currency_contract: currency_contract.contract_address, - receiver: default_receiver_creator, - } - ) - } - currency_contract - .transfer_from( - execution_info.payment_from, creator_address, creator_fees_amount - ); - } - - if ark_fees_amount > 0 { - currency_contract - .transfer_from( - execution_info.payment_from, self.admin_address.read(), ark_fees_amount - ); + match self.orderbook.fulfill_order(fulfillInfo) { + Option::Some(execute_info) => { _execute_order(ref self, execute_info); }, + Option::None => panic!("OB: failed to fulfill order"), } - // finally transfer to the seller - currency_contract - .transfer_from( - execution_info.payment_from, execution_info.payment_to, seller_amount - ); - - let nft_contract = IERC721Dispatcher { contract_address: execution_info.nft_address }; - nft_contract - .transfer_from( - execution_info.nft_from, execution_info.nft_to, execution_info.nft_token_id - ); - - let tx_info = starknet::get_tx_info().unbox(); - let transaction_hash = tx_info.transaction_hash; - let block_timestamp = starknet::info::get_block_timestamp(); - - self - .emit( - OrderExecuted { - order_hash: execution_info.order_hash, transaction_hash, block_timestamp, - } - ); - - let messaging = IAppchainMessagingDispatcher { - contract_address: self.messaging_address.read() - }; - - let vinfo = ExecutionValidationInfo { - order_hash: execution_info.order_hash, - transaction_hash, - starknet_block_timestamp: block_timestamp, - from: execution_info.nft_from, - to: execution_info.nft_to, - }; - - let mut vinfo_buf = array![]; - Serde::serialize(@vinfo, ref vinfo_buf); - - messaging - .send_message_to_appchain( - self.arkchain_orderbook_address.read(), - selector!("validate_order_execution"), - vinfo_buf.span(), - ); } } @@ -524,7 +307,8 @@ mod executor { assert!(caller == *(order.offerer), "Caller is not the offerer"); match order.route { - RouteType::Erc20ToErc721 => { + RouteType::Erc20ToErc721 | + RouteType::Erc20ToErc1155 => { assert!( _check_erc20_amount( order.currency_address, *(order.start_amount), order.offerer @@ -543,16 +327,44 @@ mod executor { Option::None => panic!("Invalid token id"), } }, + RouteType::Erc1155ToErc20 => { + match order.token_id { + Option::Some(token_id) => { + assert!( + _check_erc1155_balance( + order.token_address, token_id, order.quantity, order.offerer + ), + "Offerer does not own enough of the specified ERC1155 token" + ); + }, + Option::None => panic!("Invalid token id"), + } + } } } + fn _verify_cancel_order(self: @ContractState, vinfo: @CancelOrderInfo) { + let cancel_info = vinfo.cancelInfo; + let caller = starknet::get_caller_address(); + let canceller = *(cancel_info.canceller); + assert!(caller == canceller, "Caller is not the canceller"); + + let order_info = _get_order_info(self, *cancel_info.order_hash); + + // default value for ContractAddress is zero + // and an order's currency address shall not be zero + assert!(order_info.currency_address.is_non_zero(), "Order not found"); + assert!(order_info.offerer == canceller, "Canceller is not the offerer"); + } + fn _verify_fulfill_order(self: @ContractState, vinfo: @FulfillOrderInfo) { let fulfill_info = vinfo.fulfillInfo; let caller = starknet::get_caller_address(); let fulfiller = *(fulfill_info.fulfiller); assert!(caller == fulfiller, "Caller is not the fulfiller"); - let order_info = self.orders.read(*fulfill_info.order_hash); + let order_info = _get_order_info(self, *fulfill_info.order_hash); + // default value for ContractAddress is zero // and an order's currency address shall not be zero if order_info.currency_address.is_zero() { @@ -602,21 +414,42 @@ mod executor { ), "Fulfiller's allowance of executor is not enough" ); - assert!( - _check_erc721_owner( - @order_info.token_address, order_info.token_id, @order_info.offerer - ), - "Offerer does not own the specified ERC721 token" - ); - assert!( - _check_erc721_approval( - @order_info.token_address, - order_info.token_id, - @order_info.offerer, - @contract_address, - ), - "Executor not approved by offerer" - ); + + if _is_erc721(order_info.token_address) { + assert!( + _check_erc721_owner( + @order_info.token_address, order_info.token_id, @order_info.offerer + ), + "Offerer does not own the specified ERC721 token" + ); + assert!( + _check_erc721_approval( + @order_info.token_address, + order_info.token_id, + @order_info.offerer, + @contract_address, + ), + "Executor not approved by offerer" + ); + } + + if _is_erc1155(order_info.token_address) { + assert!( + _check_erc1155_balance( + @order_info.token_address, + @order_info.token_id, + @order_info.quantity, + @order_info.offerer + ), + "Offerer does not own the specified amount of ERC1155 token" + ); + assert!( + _check_erc1155_approval( + @order_info.token_address, @order_info.offerer, @contract_address, + ), + "Executor not approved by offerer" + ); + } } fn _verify_fulfill_offer_order( @@ -632,16 +465,32 @@ mod executor { }; assert!(order_info.token_id == token_id, "Fulfiller token id is different than order"); - assert!( - _check_erc721_owner(@order_info.token_address, token_id, @fulfiller), - "Fulfiller does not own the specified ERC721 token" - ); - assert!( - _check_erc721_approval( - @order_info.token_address, token_id, @fulfiller, @contract_address, - ), - "Executor not approved by fulfiller" - ); + if _is_erc721(order_info.token_address) { + assert!( + _check_erc721_owner(@order_info.token_address, token_id, @fulfiller), + "Fulfiller does not own the specified ERC721 token" + ); + assert!( + _check_erc721_approval( + @order_info.token_address, token_id, @fulfiller, @contract_address, + ), + "Executor not approved by fulfiller" + ); + } + + if _is_erc1155(order_info.token_address) { + assert!( + _check_erc1155_balance( + @order_info.token_address, @token_id, fulfill_info.quantity, @fulfiller + ), + "Fulfiller does not own the specified amount of ERC1155 token" + ); + assert!( + _check_erc1155_approval(@order_info.token_address, @fulfiller, @contract_address,), + "Executor not approved by fulfiller" + ); + } + assert!( _check_erc20_amount( @order_info.currency_address, order_info.start_amount, @order_info.offerer @@ -667,7 +516,7 @@ mod executor { ) { let related_order_info = match *(fulfill_info.related_order_hash) { Option::None => panic!("Fulfill auction order require a related order"), - Option::Some(related_order_hash) => self.orders.read(related_order_hash), + Option::Some(related_order_hash) => _get_order_info(self, related_order_hash), }; assert!( @order_info.currency_address == @related_order_info.currency_address, @@ -690,21 +539,42 @@ mod executor { ), "Buyer's allowance of executor is not enough" ); - assert!( - _check_erc721_owner( - @order_info.token_address, order_info.token_id, @order_info.offerer - ), - "Offerer does not own the specified ERC721 token" - ); - assert!( - _check_erc721_approval( - @order_info.token_address, - order_info.token_id, - @order_info.offerer, - @contract_address, - ), - "Executor not approved by offerer" - ); + + if _is_erc721(order_info.token_address) { + assert!( + _check_erc721_owner( + @order_info.token_address, order_info.token_id, @order_info.offerer + ), + "Offerer does not own the specified ERC721 token" + ); + assert!( + _check_erc721_approval( + @order_info.token_address, + order_info.token_id, + @order_info.offerer, + @contract_address, + ), + "Executor not approved by offerer" + ); + } + + if _is_erc1155(order_info.token_address) { + assert!( + _check_erc1155_balance( + @order_info.token_address, + @order_info.token_id, + @order_info.quantity, + @order_info.offerer + ), + "Offerer does not own the specified amount of ERC1155 token" + ); + assert!( + _check_erc1155_approval( + @order_info.token_address, @order_info.offerer, @contract_address, + ), + "Executor not approved by offerer" + ); + } } fn _verify_fulfill_collection_offer_order( @@ -719,16 +589,31 @@ mod executor { Option::Some(token_id) => token_id, }; - assert!( - _check_erc721_owner(@order_info.token_address, token_id, @fulfiller), - "Fulfiller does not own the specified ERC721 token" - ); - assert!( - _check_erc721_approval( - @order_info.token_address, token_id, @fulfiller, @contract_address, - ), - "Executor not approved by fulfiller" - ); + if _is_erc721(order_info.token_address) { + assert!( + _check_erc721_owner(@order_info.token_address, token_id, @fulfiller), + "Fulfiller does not own the specified ERC721 token" + ); + assert!( + _check_erc721_approval( + @order_info.token_address, token_id, @fulfiller, @contract_address, + ), + "Executor not approved by fulfiller" + ); + } + + if _is_erc1155(order_info.token_address) { + assert!( + _check_erc1155_balance( + @order_info.token_address, @token_id, fulfill_info.quantity, @fulfiller + ), + "Fulfiller does not own the specified amount of ERC1155 token" + ); + assert!( + _check_erc1155_approval(@order_info.token_address, @fulfiller, @contract_address,), + "Executor not approved by fulfiller" + ); + } assert!( _check_erc20_amount( @@ -747,6 +632,145 @@ mod executor { ) } + fn _execute_order(ref self: ContractState, execution_info: ExecutionInfo) { + // Check if execution_info.currency_contract_address is whitelisted + _ensure_is_not_in_maintenance(@self); + assert( + execution_info.payment_currency_chain_id == self.chain_id.read(), + 'Chain ID is not SN_MAIN' + ); + + let currency_contract = IERC20Dispatcher { + contract_address: execution_info.payment_currency_address.try_into().unwrap() + }; + + let (creator_address, creator_fees_amount) = _compute_creator_fees_amount( + @self, + @execution_info.token_address, + execution_info.payment_amount, + execution_info.token_id + ); + let (fulfill_broker_fees_amount, listing_broker_fees_amount, ark_fees_amount, _) = + _compute_fees_amount( + @self, + execution_info.fulfill_broker_address, + execution_info.listing_broker_address, + execution_info.token_address, + execution_info.token_id, + execution_info.payment_amount + ); + assert!( + execution_info + .payment_amount > (fulfill_broker_fees_amount + + listing_broker_fees_amount + + creator_fees_amount + + ark_fees_amount), + "Fees exceed payment amount" + ); + + let seller_amount = execution_info.payment_amount + - (fulfill_broker_fees_amount + + listing_broker_fees_amount + + creator_fees_amount + + ark_fees_amount); + + // split the fees + if fulfill_broker_fees_amount > 0 { + currency_contract + .transfer_from( + execution_info.payment_from, + execution_info.fulfill_broker_address, + fulfill_broker_fees_amount, + ); + } + + if listing_broker_fees_amount > 0 { + currency_contract + .transfer_from( + execution_info.payment_from, + execution_info.listing_broker_address, + listing_broker_fees_amount + ); + } + + if creator_fees_amount > 0 { + let (default_receiver_creator, _) = self.get_default_creator_fees(); + if creator_address == default_receiver_creator { + self + .emit( + CollectionFallbackFees { + collection: execution_info.token_address, + amount: creator_fees_amount, + currency_contract: currency_contract.contract_address, + receiver: default_receiver_creator, + } + ) + } + currency_contract + .transfer_from(execution_info.payment_from, creator_address, creator_fees_amount); + } + + if ark_fees_amount > 0 { + currency_contract + .transfer_from( + execution_info.payment_from, self.admin_address.read(), ark_fees_amount + ); + } + // finally transfer to the seller + if seller_amount > 0 { + currency_contract + .transfer_from( + execution_info.payment_from, execution_info.payment_to, seller_amount + ); + } + + if _is_erc721(execution_info.token_address) { + let nft_contract = IERC721Dispatcher { contract_address: execution_info.token_address }; + nft_contract + .transfer_from( + execution_info.token_from, execution_info.token_to, execution_info.token_id + ); + } + + if _is_erc1155(execution_info.token_address) { + let erc1155_contract = IERC1155Dispatcher { + contract_address: execution_info.token_address + }; + erc1155_contract + .safe_transfer_from( + execution_info.token_from, + execution_info.token_to, + execution_info.token_id, + execution_info.token_quantity, + array![].span() + ); + } + + let tx_info = starknet::get_tx_info().unbox(); + let transaction_hash = tx_info.transaction_hash; + let block_timestamp = starknet::info::get_block_timestamp(); + + let vinfo = ExecutionValidationInfo { + order_hash: execution_info.order_hash, + transaction_hash, + starknet_block_timestamp: block_timestamp, + from: execution_info.token_from, + to: execution_info.token_to, + }; + + self.orderbook.validate_order_execution(vinfo); + } + + fn _is_erc721(token_address: ContractAddress) -> bool { + let src5_dispatcher = ISRC5Dispatcher { contract_address: token_address }; + src5_dispatcher.supports_interface(IERC721_ID) + } + + fn _is_erc1155(token_address: ContractAddress) -> bool { + let src5_dispatcher = ISRC5Dispatcher { contract_address: token_address }; + src5_dispatcher.supports_interface(IERC1155_ID) + } + fn _check_erc20_amount( token_address: @ContractAddress, amount: u256, user: @ContractAddress ) -> bool { @@ -782,6 +806,20 @@ mod executor { || (contract.get_approved(token_id) == *operator) } + fn _check_erc1155_balance( + token_address: @ContractAddress, token_id: @u256, quantity: @u256, user: @ContractAddress + ) -> bool { + let contract = IERC1155Dispatcher { contract_address: *token_address }; + *quantity <= contract.balance_of(*user, *token_id) + } + + fn _check_erc1155_approval( + token_address: @ContractAddress, owner: @ContractAddress, operator: @ContractAddress + ) -> bool { + let contract = IERC1155Dispatcher { contract_address: *token_address }; + contract.is_approved_for_all(*owner, *operator) + } + fn _compute_creator_fees_amount( self: @ContractState, nft_address: @ContractAddress, payment_amount: u256, token_id: u256 ) -> (ContractAddress, u256) { @@ -838,4 +876,22 @@ mod executor { creator_fees_amount, ) } + + fn _get_order_info(self: @ContractState, order_hash: felt252) -> OrderInfo { + let order = self.orderbook.get_order(order_hash); + let order_type = self.orderbook.get_order_type(order_hash); + let token_id = match order.token_id { + Option::Some(token_id) => token_id, + Option::None => 0, + }; + OrderInfo { + order_type, + currency_address: order.currency_address, + token_address: order.token_address, + token_id, + quantity: order.quantity, + start_amount: order.start_amount, + offerer: order.offerer, + } + } } diff --git a/contracts/ark_starknet/src/interfaces.cairo b/contracts/ark_starknet/src/interfaces.cairo index ed0b1c60a..f283272b5 100644 --- a/contracts/ark_starknet/src/interfaces.cairo +++ b/contracts/ark_starknet/src/interfaces.cairo @@ -1,9 +1,9 @@ -//! Interfaces for arkchain operator. -use starknet::{ClassHash, ContractAddress}; use ark_common::protocol::order_types::ExecutionInfo; use ark_common::protocol::order_types::OrderV1; use ark_common::protocol::order_types::{FulfillInfo, CancelInfo}; use ark_oz::erc2981::FeesRatio; +//! Interfaces for arkchain operator. +use starknet::{ClassHash, ContractAddress}; #[derive(Serde, Drop)] struct FeesAmount { @@ -18,14 +18,9 @@ trait IExecutor { fn fulfill_order(ref self: T, fulfillInfo: FulfillInfo); fn cancel_order(ref self: T, cancelInfo: CancelInfo); fn create_order(ref self: T, order: OrderV1); - fn execute_order(ref self: T, execution_info: ExecutionInfo); + // fn execute_order(ref self: T, execution_info: ExecutionInfo); fn update_admin_address(ref self: T, admin_address: ContractAddress); - fn update_orderbook_address(ref self: T, orderbook_address: ContractAddress); fn update_eth_address(ref self: T, eth_address: ContractAddress); - fn update_messaging_address(ref self: T, msger_address: ContractAddress); - fn get_messaging_address(self: @T) -> ContractAddress; - fn get_orderbook_address(self: @T) -> ContractAddress; - fn update_arkchain_orderbook_address(ref self: T, orderbook_address: ContractAddress); fn set_broker_fees(ref self: T, fees_ratio: FeesRatio); fn get_broker_fees(self: @T, broker_address: ContractAddress) -> FeesRatio; fn set_ark_fees(ref self: T, fees_ratio: FeesRatio); diff --git a/contracts/ark_starknet/src/lib.cairo b/contracts/ark_starknet/src/lib.cairo index 57f65f841..c469b015e 100644 --- a/contracts/ark_starknet/src/lib.cairo +++ b/contracts/ark_starknet/src/lib.cairo @@ -1,4 +1,3 @@ -mod appchain_messaging; -mod interfaces; mod executor; +mod interfaces; diff --git a/contracts/ark_starknet/tests/common/setup.cairo b/contracts/ark_starknet/tests/common/setup.cairo index e2251c8a4..bc8aab568 100644 --- a/contracts/ark_starknet/tests/common/setup.cairo +++ b/contracts/ark_starknet/tests/common/setup.cairo @@ -1,13 +1,21 @@ +use ark_common::protocol::order_types::{OrderTrait, RouteType}; +use ark_common::protocol::order_v1::OrderV1; + +use ark_starknet::interfaces::{IExecutorDispatcher, IExecutorDispatcherTrait,}; + +use ark_tokens::erc20::{IFreeMintDispatcher, IFreeMintDispatcherTrait}; +use ark_tokens::erc721::IFreeMintDispatcher as Erc721Dispatcher; +use ark_tokens::erc721::IFreeMintDispatcherTrait as Erc721DispatcherTrait; + use serde::Serde; +use snforge_std::{ + cheat_caller_address, CheatSpan, ContractClass, ContractClassTrait, declare, DeclareResultTrait +}; use starknet::{ContractAddress, contract_address_const}; -use snforge_std::{ContractClass, ContractClassTrait, declare}; - -use ark_common::protocol::order_v1::OrderV1; -use ark_common::protocol::order_types::RouteType; fn deploy_erc20() -> ContractAddress { - let contract = declare('FreeMintERC20'); + let contract = declare("FreeMintERC20").unwrap().contract_class(); let initial_supply: u256 = 10_000_000_000_u256; let name: ByteArray = "DummyERC20"; let symbol: ByteArray = "DUMMY"; @@ -16,7 +24,7 @@ fn deploy_erc20() -> ContractAddress { initial_supply.serialize(ref calldata); name.serialize(ref calldata); symbol.serialize(ref calldata); - let erc20_address = contract.deploy(@calldata).unwrap(); + let (erc20_address, _) = contract.deploy(@calldata).unwrap(); erc20_address } @@ -29,36 +37,40 @@ fn deploy_nft(royalty: bool) -> ContractAddress { name.serialize(ref calldata); symbol.serialize(ref calldata); base_uri.serialize(ref calldata); - if royalty { + let (nft_address, _) = if royalty { let owner = contract_address_const::<'nft_owner'>(); calldata.append(owner.into()); - let contract = declare('FreeMintNFTRoyalty'); + let contract = declare("FreeMintNFTRoyalty").unwrap().contract_class(); contract.deploy(@calldata).unwrap() } else { - let contract = declare('FreeMintNFT'); + let contract = declare("FreeMintNFT").unwrap().contract_class(); contract.deploy(@calldata).unwrap() - } + }; + nft_address +} + + +fn deploy_erc1155() -> ContractAddress { + let base_uri: ByteArray = ""; + + let mut calldata: Array = array![]; + base_uri.serialize(ref calldata); + let contract = declare("FreeMintERC1155").unwrap().contract_class(); + let (erc1155_address, _) = contract.deploy(@calldata).unwrap(); + erc1155_address } fn deploy_executor() -> ContractAddress { - let messaging_contract = declare('appchain_messaging'); - let messaging_owner = contract_address_const::<'messaging_owner'>(); - let appchain_account = contract_address_const::<'messaging_account'>(); - let mut messaging_calldata: Array = array![]; - messaging_calldata.append(messaging_owner.into()); - messaging_calldata.append(appchain_account.into()); - let messaging_address = messaging_contract.deploy(@messaging_calldata).unwrap(); - - let contract = declare('executor'); + let contract = declare("executor").unwrap().contract_class(); let admin_address = contract_address_const::<'admin'>(); let eth_address = contract_address_const::<'eth'>(); let mut calldata: Array = array![]; calldata.append(admin_address.into()); calldata.append(eth_address.into()); - calldata.append(messaging_address.into()); calldata.append('SN_MAIN'); - contract.deploy(@calldata).unwrap() + let (executor_address, _) = contract.deploy(@calldata).unwrap(); + executor_address } fn setup() -> (ContractAddress, ContractAddress, ContractAddress) { @@ -68,6 +80,7 @@ fn setup() -> (ContractAddress, ContractAddress, ContractAddress) { (executor_address, erc20_address, nft_address) } + fn setup_royalty() -> (ContractAddress, ContractAddress, ContractAddress) { let erc20_address = deploy_erc20(); let nft_address = deploy_nft(true); @@ -75,7 +88,119 @@ fn setup_royalty() -> (ContractAddress, ContractAddress, ContractAddress) { (executor_address, erc20_address, nft_address) } -fn setup_order(erc20_address: ContractAddress, nft_address: ContractAddress) -> OrderV1 { +fn setup_erc1155() -> (ContractAddress, ContractAddress, ContractAddress) { + let erc20_address = deploy_erc20(); + let erc1155_address = deploy_erc1155(); + let executor_address = deploy_executor(); + (executor_address, erc20_address, erc1155_address) +} + +fn setup_order( + currency_address: ContractAddress, + nft_address: ContractAddress, + route: RouteType, + offerer: ContractAddress, + token_id: Option, + start_amount: u256, + end_amount: u256, +) -> OrderV1 { + let chain_id = 'SN_MAIN'; + let block_timestamp = starknet::get_block_timestamp(); + let end_date = block_timestamp + (30 * 24 * 60 * 60); + let data = array![]; + + OrderV1 { + route, + currency_address, + currency_chain_id: chain_id, + salt: 1, + offerer, + token_chain_id: chain_id, + token_address: nft_address, + token_id, + quantity: 1, + start_amount, + end_amount, + start_date: block_timestamp, + end_date: end_date, + broker_id: contract_address_const::<'broker_id'>(), + additional_data: data.span() + } +} + +fn setup_offer_order( + currency_address: ContractAddress, + nft_address: ContractAddress, + offerer: ContractAddress, + token_id: u256, + start_amount: u256, +) -> OrderV1 { + setup_order( + currency_address, + nft_address, + RouteType::Erc20ToErc721, + offerer, + Option::Some(token_id), + start_amount, + 0 + ) +} + +fn setup_listing_order( + currency_address: ContractAddress, + nft_address: ContractAddress, + offerer: ContractAddress, + token_id: u256, + start_amount: u256, +) -> OrderV1 { + setup_order( + currency_address, + nft_address, + RouteType::Erc721ToErc20, + offerer, + Option::Some(token_id), + start_amount, + 0 + ) +} + +fn setup_auction_order( + currency_address: ContractAddress, + nft_address: ContractAddress, + offerer: ContractAddress, + token_id: u256, + start_amount: u256, + end_amount: u256, +) -> OrderV1 { + setup_order( + currency_address, + nft_address, + RouteType::Erc721ToErc20, + offerer, + Option::Some(token_id), + start_amount, + end_amount + ) +} + +fn setup_collection_offer_order( + currency_address: ContractAddress, + nft_address: ContractAddress, + offerer: ContractAddress, + start_amount: u256, +) -> OrderV1 { + setup_order( + currency_address, + nft_address, + RouteType::Erc20ToErc721, + offerer, + Option::None, + start_amount, + 0 + ) +} + +fn setup_default_order(erc20_address: ContractAddress, nft_address: ContractAddress) -> OrderV1 { let chain_id = 'SN_MAIN'; let block_timestamp = starknet::get_block_timestamp(); let end_date = block_timestamp + (30 * 24 * 60 * 60); @@ -99,3 +224,135 @@ fn setup_order(erc20_address: ContractAddress, nft_address: ContractAddress) -> additional_data: data.span() } } + +fn create_offer_order( + executor_address: ContractAddress, + erc20_address: ContractAddress, + nft_address: ContractAddress, + token_id: u256 +) -> (felt252, ContractAddress, u256) { + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + + IFreeMintDispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let order = setup_offer_order(erc20_address, nft_address, offerer, token_id, start_amount); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + + (order.compute_order_hash(), offerer, start_amount) +} + +fn create_listing_order( + executor_address: ContractAddress, + erc20_address: ContractAddress, + nft_address: ContractAddress, + start_amount: u256 +) -> (felt252, ContractAddress, u256) { + let offerer = contract_address_const::<'offerer'>(); + + let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } + .get_current_token_id() + .into(); + Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); + + let order = setup_listing_order(erc20_address, nft_address, offerer, token_id, start_amount); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + + (order.compute_order_hash(), offerer, token_id) +} + +fn create_auction_order( + executor_address: ContractAddress, + erc20_address: ContractAddress, + nft_address: ContractAddress, + start_amount: u256, + end_amount: u256 +) -> (felt252, ContractAddress, u256) { + let offerer = contract_address_const::<'offerer'>(); + + let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } + .get_current_token_id() + .into(); + Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); + + let order = setup_auction_order( + erc20_address, nft_address, offerer, token_id, start_amount, end_amount + ); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + + (order.compute_order_hash(), offerer, token_id) +} + +fn create_collection_offer_order( + executor_address: ContractAddress, erc20_address: ContractAddress, nft_address: ContractAddress, +) -> (felt252, ContractAddress, u256) { + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + + IFreeMintDispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let order = setup_collection_offer_order(erc20_address, nft_address, offerer, start_amount); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + + (order.compute_order_hash(), offerer, start_amount) +} + +fn setup_order_erc1155( + erc20_address: ContractAddress, erc1155_address: ContractAddress, quantity: u256 +) -> OrderV1 { + let chain_id = 'SN_MAIN'; + let block_timestamp = starknet::get_block_timestamp(); + let end_date = block_timestamp + (30 * 24 * 60 * 60); + let data = array![]; + + OrderV1 { + route: RouteType::Erc20ToErc1155.into(), + currency_address: erc20_address, + currency_chain_id: chain_id, + salt: 1, + offerer: contract_address_const::<'dummy'>(), + token_chain_id: chain_id, + token_address: erc1155_address, + token_id: Option::Some(10), + quantity: quantity, + start_amount: 100_000_u256, + end_amount: 0, + start_date: block_timestamp, + end_date: end_date, + broker_id: contract_address_const::<'broker_id'>(), + additional_data: data.span() + } +} + +fn create_offer_order_erc1155( + executor_address: ContractAddress, + erc20_address: ContractAddress, + erc1155_address: ContractAddress, + token_id: u256, + quantity: u256, +) -> (felt252, ContractAddress, u256) { + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + + IFreeMintDispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let mut order = setup_order_erc1155(erc20_address, erc1155_address, quantity); + order.route = RouteType::Erc20ToErc1155.into(); + order.offerer = offerer; + order.start_amount = start_amount; + order.token_id = Option::Some(token_id); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + + (order.compute_order_hash(), offerer, start_amount) +} + diff --git a/contracts/ark_starknet/tests/integration/cancel_order.cairo b/contracts/ark_starknet/tests/integration/cancel_order.cairo new file mode 100644 index 000000000..8e71daf9f --- /dev/null +++ b/contracts/ark_starknet/tests/integration/cancel_order.cairo @@ -0,0 +1,325 @@ +use ark_common::protocol::order_types::{CancelInfo, OrderStatus, OrderType}; + +use ark_component::orderbook::OrderbookComponent; +use ark_component::orderbook::interface::{IOrderbookDispatcher, IOrderbookDispatcherTrait,}; + +use ark_starknet::executor::executor; + +use ark_starknet::interfaces::{ + IExecutorDispatcher, IExecutorDispatcherTrait, IMaintenanceDispatcher, + IMaintenanceDispatcherTrait +}; + +use snforge_std::{cheat_caller_address, CheatSpan, spy_events, EventSpyAssertionsTrait,}; + +use starknet::{ContractAddress, contract_address_const}; +use super::super::common::setup::{ + create_auction_order, create_collection_offer_order, create_listing_order, create_offer_order, + setup, setup_default_order, setup_auction_order, setup_collection_offer_order, + setup_listing_order, setup_offer_order +}; + +#[test] +fn test_cancel_offer_order() { + let (executor_address, erc20_address, nft_address) = setup(); + let token_id = 10; + let (order_hash, offerer, _) = create_offer_order( + executor_address, erc20_address, nft_address, token_id + ); + + let cancel_info = CancelInfo { + order_hash, + canceller: offerer, + token_chain_id: 'SN_MAIN', + token_address: nft_address, + token_id: Option::Some(token_id), + }; + + let mut spy = spy_events(); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.cancel_order(cancel_info); + + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderCancelled( + OrderbookComponent::OrderCancelled { + order_hash, + reason: OrderStatus::CancelledUser.into(), + order_type: OrderType::Offer, + version: OrderbookComponent::ORDER_CANCELLED_EVENT_VERSION, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::Offer, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::CancelledUser, + "Wrong order status" + ); +} + +#[test] +fn test_cancel_listing_order() { + let (executor_address, erc20_address, nft_address) = setup(); + let start_amount = 10_000_000; + + let (order_hash, offerer, token_id) = create_listing_order( + executor_address, erc20_address, nft_address, start_amount + ); + + let cancel_info = CancelInfo { + order_hash, + canceller: offerer, + token_chain_id: 'SN_MAIN', + token_address: nft_address, + token_id: Option::Some(token_id), + }; + + let mut spy = spy_events(); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.cancel_order(cancel_info); + + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderCancelled( + OrderbookComponent::OrderCancelled { + order_hash, + reason: OrderStatus::CancelledUser.into(), + order_type: OrderType::Listing, + version: OrderbookComponent::ORDER_CANCELLED_EVENT_VERSION, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::Listing, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::CancelledUser, + "Wrong order status" + ); +} + +#[test] +fn test_cancel_auction_order() { + let (executor_address, erc20_address, nft_address) = setup(); + let start_amount = 10_000_000; + let end_amount = 20_000_000; + + let (order_hash, offerer, token_id) = create_auction_order( + executor_address, erc20_address, nft_address, start_amount, end_amount + ); + + let cancel_info = CancelInfo { + order_hash, + canceller: offerer, + token_chain_id: 'SN_MAIN', + token_address: nft_address, + token_id: Option::Some(token_id), + }; + + let mut spy = spy_events(); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.cancel_order(cancel_info); + + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderCancelled( + OrderbookComponent::OrderCancelled { + order_hash, + reason: OrderStatus::CancelledUser.into(), + order_type: OrderType::Auction, + version: OrderbookComponent::ORDER_CANCELLED_EVENT_VERSION, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::Auction, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::CancelledUser, + "Wrong order status" + ); +} + +#[test] +fn test_cancel_collection_offer_order() { + let (executor_address, erc20_address, nft_address) = setup(); + let (order_hash, offerer, _) = create_collection_offer_order( + executor_address, erc20_address, nft_address + ); + + let cancel_info = CancelInfo { + order_hash, + canceller: offerer, + token_chain_id: 'SN_MAIN', + token_address: nft_address, + token_id: Option::None + }; + + let mut spy = spy_events(); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.cancel_order(cancel_info); + + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderCancelled( + OrderbookComponent::OrderCancelled { + order_hash, + reason: OrderStatus::CancelledUser.into(), + order_type: OrderType::CollectionOffer, + version: OrderbookComponent::ORDER_CANCELLED_EVENT_VERSION, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::CollectionOffer, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::CancelledUser, + "Wrong order status" + ); +} + +#[test] +// #[should_panic] +fn test_cancel_offer_order_already_cancelled() { + let (executor_address, erc20_address, nft_address) = setup(); + let token_id = 10; + let (order_hash, offerer, _) = create_offer_order( + executor_address, erc20_address, nft_address, token_id + ); + + let cancel_info = CancelInfo { + order_hash, + canceller: offerer, + token_chain_id: 'SN_MAIN', + token_address: nft_address, + token_id: Option::Some(token_id), + }; + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.cancel_order(cancel_info); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::CancelledUser, + "Wrong order status" + ); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.cancel_order(cancel_info); +} + +#[test] +#[should_panic(expected: 'OB: order not found')] +fn test_cancel_offer_order_bad_order_hash() { + let (executor_address, erc20_address, nft_address) = setup(); + let token_id = 10; + let (order_hash, offerer, _) = create_offer_order( + executor_address, erc20_address, nft_address, token_id + ); + + let cancel_info = CancelInfo { + order_hash: order_hash + 1, + canceller: offerer, + token_chain_id: 'SN_MAIN', + token_address: nft_address, + token_id: Option::Some(token_id), + }; + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.cancel_order(cancel_info); +} + + +#[test] +#[should_panic(expected: "Caller is not the canceller")] +fn test_cancel_offer_order_caller_is_not_offerer() { + let (executor_address, erc20_address, nft_address) = setup(); + let token_id = 10; + let other = contract_address_const::<'other'>(); + + let (order_hash, offerer, _) = create_offer_order( + executor_address, erc20_address, nft_address, token_id + ); + + let cancel_info = CancelInfo { + order_hash, + canceller: offerer, + token_chain_id: 'SN_MAIN', + token_address: nft_address, + token_id: Option::Some(token_id), + }; + + cheat_caller_address(executor_address, other, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.cancel_order(cancel_info); +} + + +#[test] +#[should_panic(expected: "Canceller is not the offerer")] +fn test_cancel_offer_order_offerer_is_not_the_canceller() { + let (executor_address, erc20_address, nft_address) = setup(); + let token_id = 10; + let other = contract_address_const::<'other'>(); + + let (order_hash, _offerer, _start_amount) = create_offer_order( + executor_address, erc20_address, nft_address, token_id + ); + + let cancel_info = CancelInfo { + order_hash, + canceller: other, + token_chain_id: 'SN_MAIN', + token_address: nft_address, + token_id: Option::Some(token_id), + }; + + cheat_caller_address(executor_address, other, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.cancel_order(cancel_info); +} diff --git a/contracts/ark_starknet/tests/integration/create_order.cairo b/contracts/ark_starknet/tests/integration/create_order.cairo index a41a08368..1c8a470f0 100644 --- a/contracts/ark_starknet/tests/integration/create_order.cairo +++ b/contracts/ark_starknet/tests/integration/create_order.cairo @@ -1,164 +1,776 @@ -use starknet::{ContractAddress, contract_address_const}; - +use ark_common::protocol::order_types::{OrderStatus, OrderTrait, OrderType, RouteType}; use ark_common::protocol::order_v1::OrderV1; -use ark_common::protocol::order_types::RouteType; +use ark_component::orderbook::OrderbookComponent; +use ark_component::orderbook::interface::{IOrderbookDispatcher, IOrderbookDispatcherTrait,}; + +use ark_starknet::executor::executor; use ark_starknet::interfaces::{ IExecutorDispatcher, IExecutorDispatcherTrait, IMaintenanceDispatcher, IMaintenanceDispatcherTrait }; +use ark_tokens::erc1155::IFreeMintDispatcher as Erc1155Dispatcher; +use ark_tokens::erc1155::IFreeMintDispatcherTrait as Erc1155DispatcherTrait; use ark_tokens::erc20::IFreeMintDispatcher as Erc20Dispatcher; use ark_tokens::erc20::IFreeMintDispatcherTrait as Erc20DispatcherTrait; use ark_tokens::erc721::IFreeMintDispatcher as Erc721Dispatcher; use ark_tokens::erc721::IFreeMintDispatcherTrait as Erc721DispatcherTrait; -use snforge_std as snf; -use snf::{ContractClass, ContractClassTrait, CheatTarget}; +use openzeppelin::token::erc721::interface::{IERC721Dispatcher, IERC721DispatcherTrait}; + +use snforge_std::{ + cheat_caller_address, CheatSpan, spy_events, EventSpyAssertionsTrait, + start_cheat_block_timestamp_global, stop_cheat_block_timestamp_global +}; +use starknet::{ContractAddress, contract_address_const}; -use super::super::common::setup::{setup, setup_order}; +use super::super::common::setup::{ + setup, setup_auction_order, setup_collection_offer_order, setup_listing_order, + setup_offer_order, setup_erc1155, setup_order_erc1155 +}; +// +// ERC 721 +// #[test] -fn test_create_order_erc20_to_erc721_ok() { +fn test_create_offer_order_ok() { let (executor_address, erc20_address, nft_address) = setup(); let offerer = contract_address_const::<'offerer'>(); let start_amount = 10_000_000; - + let token_id = 10_u256; Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); - let mut order = setup_order(erc20_address, nft_address); - order.offerer = offerer; - order.start_amount = start_amount; + let order = setup_offer_order(erc20_address, nft_address, offerer, token_id, start_amount); + let order_hash = order.compute_order_hash(); + let order_version = order.get_version(); - snf::start_prank(CheatTarget::One(executor_address), offerer); + let mut spy = spy_events(); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); + + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderPlaced( + OrderbookComponent::OrderPlaced { + order_hash, + order_version, + order_type: OrderType::Offer, + version: OrderbookComponent::ORDER_PLACED_EVENT_VERSION, + cancelled_order_hash: Option::None, + order, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::Offer, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::Open, + "Wrong order status" + ); } #[test] -fn test_create_order_erc721_to_erc20_ok() { +fn test_create_listing_order_ok() { let (executor_address, erc20_address, nft_address) = setup(); let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } + .get_current_token_id() + .into(); + Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); + + let order = setup_listing_order(erc20_address, nft_address, offerer, token_id, start_amount); + let order_hash = order.compute_order_hash(); + let order_version = order.get_version(); + + let mut spy = spy_events(); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderPlaced( + OrderbookComponent::OrderPlaced { + order_hash, + order_version, + order_type: OrderType::Listing, + version: OrderbookComponent::ORDER_PLACED_EVENT_VERSION, + cancelled_order_hash: Option::None, + order, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::Listing, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::Open, + "Wrong order status" + ); +} + +#[test] +fn test_create_auction_order_ok() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + let end_amount = start_amount * 2; let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } .get_current_token_id() .into(); Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); - let mut order = setup_order(erc20_address, nft_address); - order.route = RouteType::Erc721ToErc20.into(); - order.offerer = offerer; - order.token_id = Option::Some(token_id); + let order = setup_auction_order( + erc20_address, nft_address, offerer, token_id, start_amount, end_amount + ); + let order_hash = order.compute_order_hash(); + let order_version = order.get_version(); - snf::start_prank(CheatTarget::One(executor_address), offerer); + let mut spy = spy_events(); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); + + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderPlaced( + OrderbookComponent::OrderPlaced { + order_hash, + order_version, + order_type: OrderType::Auction, + version: OrderbookComponent::ORDER_PLACED_EVENT_VERSION, + cancelled_order_hash: Option::None, + order, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::Auction, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::Open, + "Wrong order status" + ); } +#[test] +fn test_create_collection_offer_order_ok() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let order = setup_collection_offer_order(erc20_address, nft_address, offerer, start_amount); + let order_hash = order.compute_order_hash(); + let order_version = order.get_version(); + + let mut spy = spy_events(); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderPlaced( + OrderbookComponent::OrderPlaced { + order_hash, + order_version, + order_type: OrderType::CollectionOffer, + version: OrderbookComponent::ORDER_PLACED_EVENT_VERSION, + cancelled_order_hash: Option::None, + order, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::CollectionOffer, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::Open, + "Wrong order status" + ); +} #[test] -#[should_panic(expected: ("Caller is not the offerer",))] -fn test_create_order_offerer_shall_be_caller() { +#[should_panic(expected: "Caller is not the offerer")] +fn test_create_offer_order_offerer_shall_be_caller() { let (executor_address, erc20_address, nft_address) = setup(); let offerer = contract_address_const::<'offerer'>(); let caller = contract_address_const::<'caller'>(); + let start_amount = 10_000_000; + let token_id = 10_u256; - let mut order = setup_order(erc20_address, nft_address); - order.offerer = offerer; + Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); - snf::start_prank(CheatTarget::One(executor_address), caller); + let order = setup_offer_order(erc20_address, nft_address, offerer, token_id, start_amount); + + cheat_caller_address(executor_address, caller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Offerer does not own enough ERC20 tokens",))] -fn test_create_order_offerer_not_enough_erc20_tokens() { +#[should_panic(expected: "Offerer does not own enough ERC20 tokens")] +fn test_create_offer_order_offerer_not_enough_erc20_tokens() { let (executor_address, erc20_address, nft_address) = setup(); let offerer = contract_address_const::<'offerer'>(); let start_amount = 10_000_000; let minted = 10_000; + let token_id = 10_u256; Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, minted); - let mut order = setup_order(erc20_address, nft_address); - order.offerer = offerer; - order.start_amount = start_amount; + let order = setup_offer_order(erc20_address, nft_address, offerer, token_id, start_amount); - snf::start_prank(CheatTarget::One(executor_address), offerer); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Offerer does not own the specified ERC721 token",))] -fn test_create_order_offerer_not_own_ec721_token() { +#[should_panic(expected: "Offerer does not own the specified ERC721 token")] +fn test_create_listing_order_offerer_not_own_ec721_token() { let (executor_address, erc20_address, nft_address) = setup(); let offerer = contract_address_const::<'offerer'>(); let other = contract_address_const::<'other'>(); + let start_amount = 10_000_000; let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } .get_current_token_id() .into(); Erc721Dispatcher { contract_address: nft_address }.mint(other, 'base_uri'); - let mut order = setup_order(erc20_address, nft_address); - order.route = RouteType::Erc721ToErc20.into(); - order.offerer = offerer; - order.token_id = Option::Some(token_id); + let order = setup_listing_order(erc20_address, nft_address, offerer, token_id, start_amount); - snf::start_prank(CheatTarget::One(executor_address), offerer); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ('Executor not enabled',))] -fn test_create_order_erc20_to_erc721_disabled() { +#[should_panic(expected: 'Executor not enabled')] +fn test_create_offer_order_disabled() { let (executor_address, erc20_address, nft_address) = setup(); let admin = contract_address_const::<'admin'>(); let offerer = contract_address_const::<'offerer'>(); let start_amount = 10_000_000; + let token_id = 10_u256; Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); - let mut order = setup_order(erc20_address, nft_address); - order.offerer = offerer; - order.start_amount = start_amount; + let order = setup_offer_order(erc20_address, nft_address, offerer, token_id, start_amount); - snf::start_prank(CheatTarget::One(executor_address), admin); + cheat_caller_address(executor_address, admin, CheatSpan::TargetCalls(1)); IMaintenanceDispatcher { contract_address: executor_address }.set_maintenance_mode(true); - snf::stop_prank(CheatTarget::One(executor_address)); - snf::start_prank(CheatTarget::One(executor_address), offerer); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ('Executor not enabled',))] -fn test_create_order_erc721_to_erc20_disabled() { +#[should_panic(expected: 'Executor not enabled')] +fn test_create_listing_order_disabled() { let (executor_address, erc20_address, nft_address) = setup(); let admin = contract_address_const::<'admin'>(); let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } + .get_current_token_id() + .into(); + Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); + + let order = setup_listing_order(erc20_address, nft_address, offerer, token_id, start_amount); + cheat_caller_address(executor_address, admin, CheatSpan::TargetCalls(1)); + IMaintenanceDispatcher { contract_address: executor_address }.set_maintenance_mode(true); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); +} + +#[test] +#[should_panic(expected: 'OB: order already exists')] +fn test_create_offer_order_twice() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + let token_id = 10_u256; + Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let order = setup_offer_order(erc20_address, nft_address, offerer, token_id, start_amount); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(2)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); +} + +#[test] +#[should_panic(expected: 'OB: order already exists')] +fn test_create_listing_order_twice() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } .get_current_token_id() .into(); Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); - let mut order = setup_order(erc20_address, nft_address); - order.route = RouteType::Erc721ToErc20.into(); + let order = setup_listing_order(erc20_address, nft_address, offerer, token_id, start_amount); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(2)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); +} + +#[test] +#[should_panic(expected: 'OB: order already exists')] +fn test_create_auction_order_twice() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + let end_amount = start_amount * 2; + let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } + .get_current_token_id() + .into(); + Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); + + let order = setup_auction_order( + erc20_address, nft_address, offerer, token_id, start_amount, end_amount + ); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(2)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); +} + +#[test] +#[should_panic(expected: 'OB: order already exists')] +fn test_create_collection_offer_order_twice() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let order = setup_collection_offer_order(erc20_address, nft_address, offerer, start_amount); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(2)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); +} + +#[test] +#[should_panic(expected: 'END_DATE_IN_THE_PAST')] +fn test_create_offer_order_expired() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + let token_id = 10_u256; + Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let mut order = setup_offer_order(erc20_address, nft_address, offerer, token_id, start_amount); + let current = starknet::get_block_timestamp(); + order.end_date = current + 10; + start_cheat_block_timestamp_global(current + 30); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + stop_cheat_block_timestamp_global(); +} + +#[test] +#[should_panic(expected: 'END_DATE_IN_THE_PAST')] +fn test_create_listing_order_expired() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } + .get_current_token_id() + .into(); + Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); + + let mut order = setup_listing_order( + erc20_address, nft_address, offerer, token_id, start_amount + ); + let current = starknet::get_block_timestamp(); + order.end_date = current + 10; + start_cheat_block_timestamp_global(current + 30); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + stop_cheat_block_timestamp_global(); +} + +#[test] +#[should_panic(expected: 'END_DATE_IN_THE_PAST')] +fn test_create_auction_order_expired() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + let end_amount = start_amount * 2; + let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } + .get_current_token_id() + .into(); + Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); + + let mut order = setup_auction_order( + erc20_address, nft_address, offerer, token_id, start_amount, end_amount + ); + let current = starknet::get_block_timestamp(); + order.end_date = current + 10; + start_cheat_block_timestamp_global(current + 30); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + stop_cheat_block_timestamp_global(); +} + +#[test] +#[should_panic(expected: 'END_DATE_IN_THE_PAST')] +fn test_create_collection_offer_order_expired() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let mut order = setup_collection_offer_order(erc20_address, nft_address, offerer, start_amount); + let current = starknet::get_block_timestamp(); + order.end_date = current + 10; + start_cheat_block_timestamp_global(current + 30); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + stop_cheat_block_timestamp_global(); +} + +// +// ERC1155 +// + +#[test] +fn test_create_order_erc20_to_erc1155_ok() { + let (executor_address, erc20_address, erc1155_address) = setup_erc1155(); + let offerer = contract_address_const::<'offerer'>(); + let quantity = 50_u256; + let start_amount = 10_000_000; + + Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let mut order = setup_order_erc1155(erc20_address, erc1155_address, quantity); + order.route = RouteType::Erc20ToErc1155.into(); + order.offerer = offerer; + order.start_amount = start_amount; + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); +} + +#[test] +fn test_create_order_erc1155_to_erc20_ok() { + let (executor_address, erc20_address, erc1155_address) = setup_erc1155(); + let offerer = erc1155_address; + let quantity = 50_u256; + + let token_id = Erc1155Dispatcher { contract_address: erc1155_address }.mint(offerer, quantity); + + let mut order = setup_order_erc1155(erc20_address, erc1155_address, quantity); + order.route = RouteType::Erc1155ToErc20.into(); + order.offerer = offerer; + order.token_id = Option::Some(token_id.into()); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); +} + +#[test] +#[should_panic(expected: "Offerer does not own enough of the specified ERC1155 token")] +fn test_create_order_offerer_not_own_enough_erc1155_token() { + let (executor_address, erc20_address, erc1155_address) = setup_erc1155(); + let offerer = erc1155_address; + let quantity = 50_u256; + + let token_id = Erc1155Dispatcher { contract_address: erc1155_address }.mint(offerer, 2_u256); + + let mut order = setup_order_erc1155(erc20_address, erc1155_address, quantity); + order.route = RouteType::Erc1155ToErc20.into(); + order.offerer = offerer; + order.token_id = Option::Some(token_id); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); +} + +#[test] +#[should_panic(expected: 'Executor not enabled')] +fn test_create_order_erc20_to_erc1155_disabled() { + let (executor_address, erc20_address, erc1155_address) = setup_erc1155(); + let admin = contract_address_const::<'admin'>(); + let offerer = contract_address_const::<'offerer'>(); + let start_amount = 10_000_000; + let quantity = 50_u256; + + Erc20Dispatcher { contract_address: erc20_address }.mint(offerer, start_amount); + + let mut order = setup_order_erc1155(erc20_address, erc1155_address, quantity); + order.route = RouteType::Erc20ToErc1155.into(); + order.offerer = offerer; + order.start_amount = start_amount; + + cheat_caller_address(executor_address, admin, CheatSpan::TargetCalls(1)); + IMaintenanceDispatcher { contract_address: executor_address }.set_maintenance_mode(true); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); +} + +#[test] +#[should_panic(expected: 'Executor not enabled')] +fn test_create_order_erc1155_to_erc20_disabled() { + let (executor_address, erc20_address, erc1155_address) = setup_erc1155(); + let admin = contract_address_const::<'admin'>(); + let offerer = erc1155_address; + let quantity = 50_u256; + + let token_id = Erc1155Dispatcher { contract_address: erc1155_address }.mint(offerer, quantity); + + let mut order = setup_order_erc1155(erc20_address, erc1155_address, quantity); + order.route = RouteType::Erc1155ToErc20.into(); order.offerer = offerer; order.token_id = Option::Some(token_id); - snf::start_prank(CheatTarget::One(executor_address), admin); + cheat_caller_address(executor_address, admin, CheatSpan::TargetCalls(1)); IMaintenanceDispatcher { contract_address: executor_address }.set_maintenance_mode(true); - snf::stop_prank(CheatTarget::One(executor_address)); - snf::start_prank(CheatTarget::One(executor_address), offerer); + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); +} + + +#[test] +fn test_create_listing_order_transfer_token_to_other_user() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let other_offerer = contract_address_const::<'other_offerer'>(); + + let start_amount = 10_000_000; + let other_start_amount = 20_000_000; + + let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } + .get_current_token_id() + .into(); + Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); + + let order = setup_listing_order(erc20_address, nft_address, offerer, token_id, start_amount); + let order_hash = order.compute_order_hash(); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + + cheat_caller_address(nft_address, offerer, CheatSpan::TargetCalls(1)); + IERC721Dispatcher { contract_address: nft_address } + .transfer_from(offerer, other_offerer, token_id); + + let other_order = setup_listing_order( + erc20_address, nft_address, other_offerer, token_id, other_start_amount + ); + let other_order_hash = other_order.compute_order_hash(); + let order_version = other_order.get_version(); + + let mut spy = spy_events(); + cheat_caller_address(executor_address, other_offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(other_order); + + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderCancelled( + OrderbookComponent::OrderCancelled { + order_hash, + reason: OrderStatus::CancelledByNewOrder.into(), + order_type: OrderType::Listing, + version: OrderbookComponent::ORDER_CANCELLED_EVENT_VERSION, + } + ) + ) + ), + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderPlaced( + OrderbookComponent::OrderPlaced { + order_hash: other_order_hash, + order_version, + order_type: OrderType::Listing, + version: OrderbookComponent::ORDER_PLACED_EVENT_VERSION, + cancelled_order_hash: Option::Some(order_hash), + order: other_order, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::Listing, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address } + .get_order_type(other_order_hash), + OrderType::Listing, + "Wrong other order type" + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::CancelledByNewOrder, + "Wrong order status" + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address } + .get_order_status(other_order_hash), + OrderStatus::Open, + "Wrong other order status" + ); +} + +#[test] +fn test_create_auction_order_transfer_token_to_other_user() { + let (executor_address, erc20_address, nft_address) = setup(); + let offerer = contract_address_const::<'offerer'>(); + let other_offerer = contract_address_const::<'other_offerer'>(); + + let start_amount = 10_000_000; + let other_start_amount = 15_000_000; + let end_amount = start_amount * 2; + + let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } + .get_current_token_id() + .into(); + Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); + + let order = setup_auction_order( + erc20_address, nft_address, offerer, token_id, start_amount, end_amount + ); + let order_hash = order.compute_order_hash(); + + cheat_caller_address(executor_address, offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(order); + + cheat_caller_address(nft_address, offerer, CheatSpan::TargetCalls(1)); + IERC721Dispatcher { contract_address: nft_address } + .transfer_from(offerer, other_offerer, token_id); + + let other_order = setup_auction_order( + erc20_address, nft_address, other_offerer, token_id, other_start_amount, end_amount + ); + let other_order_hash = other_order.compute_order_hash(); + let order_version = other_order.get_version(); + + let mut spy = spy_events(); + cheat_caller_address(executor_address, other_offerer, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.create_order(other_order); + + spy + .assert_emitted( + @array![ + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderCancelled( + OrderbookComponent::OrderCancelled { + order_hash, + reason: OrderStatus::CancelledByNewOrder.into(), + order_type: OrderType::Auction, + version: OrderbookComponent::ORDER_CANCELLED_EVENT_VERSION, + } + ) + ) + ), + ( + executor_address, + executor::Event::OrderbookEvent( + OrderbookComponent::Event::OrderPlaced( + OrderbookComponent::OrderPlaced { + order_hash: other_order_hash, + order_version, + order_type: OrderType::Auction, + version: OrderbookComponent::ORDER_PLACED_EVENT_VERSION, + cancelled_order_hash: Option::Some(order_hash), + order: other_order, + } + ) + ) + ) + ] + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_type(order_hash), + OrderType::Auction, + "Wrong order type" + ); + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address } + .get_order_type(other_order_hash), + OrderType::Auction, + "Wrong other order type" + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address }.get_order_status(order_hash), + OrderStatus::CancelledByNewOrder, + "Wrong order status" + ); + + assert_eq!( + IOrderbookDispatcher { contract_address: executor_address } + .get_order_status(other_order_hash), + OrderStatus::Open, + "Wrong other order status" + ); } diff --git a/contracts/ark_starknet/tests/integration/execute_order.cairo b/contracts/ark_starknet/tests/integration/execute_order.cairo index 1fee4bad2..2f062653e 100644 --- a/contracts/ark_starknet/tests/integration/execute_order.cairo +++ b/contracts/ark_starknet/tests/integration/execute_order.cairo @@ -1,9 +1,5 @@ -use starknet::{ContractAddress, contract_address_const}; - -use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; -use openzeppelin::token::erc721::interface::{IERC721Dispatcher, IERC721DispatcherTrait}; -use ark_common::protocol::order_v1::OrderV1; use ark_common::protocol::order_types::{FulfillInfo, ExecutionInfo, OrderTrait, RouteType}; +use ark_common::protocol::order_v1::OrderV1; use ark_oz::erc2981::{IERC2981SetupDispatcher, IERC2981SetupDispatcherTrait}; @@ -16,10 +12,14 @@ use ark_tokens::erc20::{IFreeMintDispatcher, IFreeMintDispatcherTrait}; use ark_tokens::erc721::IFreeMintDispatcher as Erc721Dispatcher; use ark_tokens::erc721::IFreeMintDispatcherTrait as Erc721DispatcherTrait; -use snforge_std as snf; -use snf::{cheatcodes::{events::EventFetcher, events::EventAssertions,}, event_name_hash,}; -use snf::{ContractClass, ContractClassTrait, CheatTarget, spy_events, SpyOn}; +use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; +use openzeppelin::token::erc721::interface::{IERC721Dispatcher, IERC721DispatcherTrait}; +use snforge_std::{ + ContractClass, ContractClassTrait, cheat_caller_address, CheatSpan, spy_events, + EventSpyAssertionsTrait, EventSpyTrait, Event, EventsFilterTrait, +}; +use starknet::{ContractAddress, contract_address_const}; use super::super::common::setup::{setup, setup_order, setup_royalty}; fn create_fulfill_info( @@ -32,6 +32,7 @@ fn create_fulfill_info( token_chain_id: 'SN_MAIN', token_address: token_address, token_id: Option::Some(token_id), + quantity: 1_u256, fulfill_broker_address: contract_address_const::<'broker'>() } } @@ -52,10 +53,11 @@ fn create_execution_info( ) -> ExecutionInfo { ExecutionInfo { order_hash: order_hash, - nft_address: nft_address, - nft_from: nft_from, - nft_to: nft_to, - nft_token_id: nft_token_id, + token_address: nft_address, + token_from: nft_from, + token_to: nft_to, + token_id: nft_token_id, + token_quantity: 1_u256, payment_from: payment_from, payment_to: payment_to, payment_amount: payment_amount, @@ -93,25 +95,21 @@ fn setup_execute_order( order.start_amount = start_amount; order.token_id = Option::Some(token_id); - snf::start_prank(CheatTarget::One(executor.contract_address), offerer); + cheat_caller_address(executor.contract_address, offerer, CheatSpan::TargetCalls(1)); executor.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); let order_hash = order.compute_order_hash(); - snf::start_prank(CheatTarget::One(erc20_address), offerer); + cheat_caller_address(erc20_address, offerer, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(nft_address), fulfiller); + cheat_caller_address(nft_address, fulfiller, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); executor.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); let execution_info = create_execution_info( order_hash, @@ -167,13 +165,11 @@ fn test_execute_order_check_brokers_fees_ok() { let fulfill_fees_ratio = FeesRatio { numerator: 10, denominator: 100 }; let listing_fees_ratio = FeesRatio { numerator: 5, denominator: 100 }; - snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker); + cheat_caller_address(executor.contract_address, fulfill_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(fulfill_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker); + cheat_caller_address(executor.contract_address, listing_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(listing_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); assert_eq!( executor.get_broker_fees(fulfill_broker), @@ -218,17 +214,14 @@ fn test_execute_order_check_ark_fees_ok() { let listing_fees_ratio = FeesRatio { numerator: 5, denominator: 100 }; - snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker); + cheat_caller_address(executor.contract_address, fulfill_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(fulfill_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker); + cheat_caller_address(executor.contract_address, listing_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(listing_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), admin_address); + cheat_caller_address(executor.contract_address, admin_address, CheatSpan::TargetCalls(1)); executor.set_ark_fees(ark_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); let admin_balance = erc20.balance_of(admin_address); let admin_delta = 50_000; // 0.5% @@ -264,13 +257,11 @@ fn test_execute_order_erc2981_default_royalty_check_fees_ok() { let listing_fees_ratio = FeesRatio { numerator: 5, denominator: 100 }; - snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker); + cheat_caller_address(executor.contract_address, fulfill_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(fulfill_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker); + cheat_caller_address(executor.contract_address, listing_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(listing_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); assert_eq!( executor.get_broker_fees(fulfill_broker), @@ -298,14 +289,13 @@ fn test_execute_order_erc2981_default_royalty_check_fees_ok() { - listing_broker_delta - creator_delta; - snf::start_prank(CheatTarget::One(nft_address), nft_owner); + cheat_caller_address(nft_address, nft_owner, CheatSpan::TargetCalls(1)); IERC2981SetupDispatcher { contract_address: nft_address } .set_default_royalty(creator, FeesRatio { numerator: 2, denominator: 100 }); - snf::stop_prank(CheatTarget::One(nft_address)); - let mut spy = spy_events(SpyOn::One(executor_address)); + let mut spy = spy_events(); IExecutorDispatcher { contract_address: executor_address }.execute_order(execution_info); - spy.fetch_events(); + let events = spy.get_events().emitted_by(executor_address); assert_eq!( erc20.balance_of(fulfill_broker) - fulfill_broker_balance, @@ -329,10 +319,10 @@ fn test_execute_order_erc2981_default_royalty_check_fees_ok() { "Fulfiller balance not correct" ); - assert_eq!(spy.events.len(), 1, "Expected 1 events"); - let (_, event) = spy.events.at(0); + assert_eq!(events.events.len(), 1, "Expected 1 events"); + let (_, event) = events.events.at(0); assert_eq!(event.keys.len(), 3, "There should be 3 keys"); - assert!(event.keys.at(0) == @event_name_hash('OrderExecuted'), "Wrong event name"); + assert_eq!(event.keys.at(0), @selector!("OrderExecuted"), "Wrong event name"); } #[test] @@ -360,13 +350,11 @@ fn test_execute_order_erc2981_token_royalty_check_fees_ok() { let listing_fees_ratio = FeesRatio { numerator: 5, denominator: 100 }; - snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker); + cheat_caller_address(executor.contract_address, fulfill_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(fulfill_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker); + cheat_caller_address(executor.contract_address, listing_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(listing_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); assert_eq!( executor.get_broker_fees(fulfill_broker), @@ -398,14 +386,13 @@ fn test_execute_order_erc2981_token_royalty_check_fees_ok() { - creator_delta - default_creator_delta; - snf::start_prank(CheatTarget::One(nft_address), nft_owner); + cheat_caller_address(nft_address, nft_owner, CheatSpan::TargetCalls(2)); IERC2981SetupDispatcher { contract_address: nft_address } .set_token_royalty( execution_info.nft_token_id, creator, FeesRatio { numerator: 3, denominator: 100 } ); IERC2981SetupDispatcher { contract_address: nft_address } .set_default_royalty(default_creator, FeesRatio { numerator: 2, denominator: 100 }); - snf::stop_prank(CheatTarget::One(nft_address)); IExecutorDispatcher { contract_address: executor_address }.execute_order(execution_info); assert_eq!( @@ -459,12 +446,11 @@ fn test_execute_order_non_erc2981_default_royalty_check_fees_ok() { let listing_fees_ratio = FeesRatio { numerator: 5, denominator: 100 }; - snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker); + cheat_caller_address(executor.contract_address, fulfill_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(fulfill_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker); + + cheat_caller_address(executor.contract_address, listing_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(listing_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); assert_eq!( executor.get_broker_fees(fulfill_broker), @@ -492,17 +478,16 @@ fn test_execute_order_non_erc2981_default_royalty_check_fees_ok() { - listing_broker_delta - creator_delta; - snf::start_prank(CheatTarget::One(executor.contract_address), admin_address); + cheat_caller_address(executor.contract_address, admin_address, CheatSpan::TargetCalls(2)); executor.set_default_creator_fees(creator, FeesRatio { numerator: 2, denominator: 100 }); executor .set_collection_creator_fees( fake_nft_address, creator, FeesRatio { numerator: 4, denominator: 1000 } ); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - let mut spy = spy_events(SpyOn::One(executor_address)); + let mut spy = spy_events(); IExecutorDispatcher { contract_address: executor_address }.execute_order(execution_info); - spy.fetch_events(); + let events = spy.get_events().emitted_by(executor_address); assert_eq!( erc20.balance_of(fulfill_broker) - fulfill_broker_balance, @@ -526,16 +511,16 @@ fn test_execute_order_non_erc2981_default_royalty_check_fees_ok() { "Fulfiller balance not correct" ); - assert_eq!(spy.events.len(), 2, "Expected 2 events"); - let (_, event) = spy.events.at(0); + assert_eq!(events.events.len(), 2, "Expected 2 events"); + let (_, event) = events.events.at(0); assert_eq!(event.keys.len(), 4, "There should be 4 keys"); - assert_eq!(@event_name_hash('CollectionFallbackFees'), event.keys.at(0), "Wrong event name"); + assert_eq!(@selector!("CollectionFallbackFees"), event.keys.at(0), "Wrong event name"); assert_eq!(nft_address, (*event.keys.at(1)).try_into().unwrap(), "Wrong collection address"); assert_eq!(creator_delta.low, (*event.keys.at(2)).try_into().unwrap(), "Wrong low amount"); assert_eq!(creator_delta.high, (*event.keys.at(3)).try_into().unwrap(), "Wrong high amount"); - let (_, event) = spy.events.at(1); + let (_, event) = events.events.at(1); assert_eq!(event.keys.len(), 3, "There should be 3 keys"); - assert_eq!(@event_name_hash('OrderExecuted'), event.keys.at(0), "Wrong event name"); + assert_eq!(@selector!("OrderExecuted"), event.keys.at(0), "Wrong event name"); } #[test] @@ -560,12 +545,11 @@ fn test_execute_order_non_erc2981_collection_royalty_check_fees_ok() { let listing_fees_ratio = FeesRatio { numerator: 5, denominator: 100 }; - snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker); + cheat_caller_address(executor.contract_address, fulfill_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(fulfill_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker); + + cheat_caller_address(executor.contract_address, listing_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(listing_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); assert_eq!( executor.get_broker_fees(fulfill_broker), @@ -593,13 +577,12 @@ fn test_execute_order_non_erc2981_collection_royalty_check_fees_ok() { - listing_broker_delta - creator_delta; - snf::start_prank(CheatTarget::One(executor.contract_address), admin_address); + cheat_caller_address(executor.contract_address, admin_address, CheatSpan::TargetCalls(2)); executor.set_default_creator_fees(other_creator, FeesRatio { numerator: 4, denominator: 100 }); executor .set_collection_creator_fees( nft_address, creator, FeesRatio { numerator: 2, denominator: 100 } ); - snf::stop_prank(CheatTarget::One(executor.contract_address)); IExecutorDispatcher { contract_address: executor_address }.execute_order(execution_info); assert_eq!( @@ -626,7 +609,7 @@ fn test_execute_order_non_erc2981_collection_royalty_check_fees_ok() { } #[test] -#[should_panic(expected: ("Fees exceed payment amount",))] +#[should_panic(expected: "Fees exceed payment amount")] fn test_execute_order_check_fee_too_much_fees() { let fulfiller = contract_address_const::<'fulfiller'>(); let listing_broker = contract_address_const::<'listing_broker'>(); @@ -646,12 +629,11 @@ fn test_execute_order_check_fee_too_much_fees() { let listing_fees_ratio = FeesRatio { numerator: 60, denominator: 100 }; - snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker); + cheat_caller_address(executor.contract_address, fulfill_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(fulfill_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker); + + cheat_caller_address(executor.contract_address, listing_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(listing_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); IExecutorDispatcher { contract_address: executor_address }.execute_order(execution_info); assert_eq!(erc20.balance_of(fulfill_broker), 1_000_000, "Fulfill broker balance not correct"); @@ -659,7 +641,7 @@ fn test_execute_order_check_fee_too_much_fees() { } #[test] -#[should_panic(expected: ('Executor not enabled',))] +#[should_panic(expected: 'Executor not enabled')] fn test_execute_order_disabled() { let fulfiller = contract_address_const::<'fulfiller'>(); let listing_broker = contract_address_const::<'listing_broker'>(); @@ -672,9 +654,8 @@ fn test_execute_order_disabled() { admin_address, offerer, fulfiller, listing_broker, fulfill_broker, start_amount, false ); - snf::start_prank(CheatTarget::One(executor_address), admin_address); + cheat_caller_address(executor_address, admin_address, CheatSpan::TargetCalls(1)); IMaintenanceDispatcher { contract_address: executor_address }.set_maintenance_mode(true); - snf::stop_prank(CheatTarget::One(executor_address)); IExecutorDispatcher { contract_address: executor_address }.execute_order(execution_info); } diff --git a/contracts/ark_starknet/tests/integration/fees_amount.cairo b/contracts/ark_starknet/tests/integration/fees_amount.cairo index 23d90c4ec..1000e32ba 100644 --- a/contracts/ark_starknet/tests/integration/fees_amount.cairo +++ b/contracts/ark_starknet/tests/integration/fees_amount.cairo @@ -1,12 +1,9 @@ -use starknet::{ContractAddress, contract_address_const}; - use ark_starknet::interfaces::{ IExecutorDispatcher, IExecutorDispatcherTrait, FeesAmount, FeesRatio }; -use snforge_std as snf; -use snf::{ContractClass, ContractClassTrait, CheatTarget}; - +use snforge_std::{cheat_caller_address, CheatSpan}; +use starknet::{ContractAddress, contract_address_const}; use super::super::common::setup::setup; @@ -26,18 +23,15 @@ fn test_get_fees_amount_default_creator() { let ark_fees_ratio = FeesRatio { numerator: 1, denominator: 100 }; let default_creator_fees_ratio = FeesRatio { numerator: 2, denominator: 100 }; - snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker); + cheat_caller_address(executor.contract_address, fulfill_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(fulfill_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker); + cheat_caller_address(executor.contract_address, listing_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(listing_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), admin); + cheat_caller_address(executor.contract_address, admin, CheatSpan::TargetCalls(2)); executor.set_ark_fees(ark_fees_ratio); executor.set_default_creator_fees(creator, default_creator_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); let fees_amount = executor .get_fees_amount(fulfill_broker, listing_broker, nft_address, 1, amount); @@ -65,19 +59,16 @@ fn test_get_fees_amount_collection_creator() { let default_creator_fees_ratio = FeesRatio { numerator: 2, denominator: 100 }; let collection_creator_fees_ratio = FeesRatio { numerator: 3, denominator: 100 }; - snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker); + cheat_caller_address(executor.contract_address, fulfill_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(fulfill_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker); + cheat_caller_address(executor.contract_address, listing_broker, CheatSpan::TargetCalls(1)); executor.set_broker_fees(listing_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); - snf::start_prank(CheatTarget::One(executor.contract_address), admin); + cheat_caller_address(executor.contract_address, admin, CheatSpan::TargetCalls(3)); executor.set_ark_fees(ark_fees_ratio); executor.set_default_creator_fees(creator, default_creator_fees_ratio); executor.set_collection_creator_fees(nft_address, creator, collection_creator_fees_ratio); - snf::stop_prank(CheatTarget::One(executor.contract_address)); let fees_amount = executor .get_fees_amount(fulfill_broker, listing_broker, nft_address, 1, amount); diff --git a/contracts/ark_starknet/tests/integration/fulfill_order.cairo b/contracts/ark_starknet/tests/integration/fulfill_order.cairo index f2b23abe4..21dae3f9e 100644 --- a/contracts/ark_starknet/tests/integration/fulfill_order.cairo +++ b/contracts/ark_starknet/tests/integration/fulfill_order.cairo @@ -1,121 +1,30 @@ -use starknet::{ContractAddress, contract_address_const}; - -use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; -use openzeppelin::token::erc721::interface::{IERC721Dispatcher, IERC721DispatcherTrait}; -use ark_common::protocol::order_v1::OrderV1; use ark_common::protocol::order_types::{FulfillInfo, OrderTrait, RouteType}; +use ark_common::protocol::order_v1::OrderV1; use ark_starknet::interfaces::{ IExecutorDispatcher, IExecutorDispatcherTrait, IMaintenanceDispatcher, IMaintenanceDispatcherTrait }; +use ark_tokens::erc1155::IFreeMintDispatcher as Erc1155Dispatcher; +use ark_tokens::erc1155::IFreeMintDispatcherTrait as Erc1155DispatcherTrait; use ark_tokens::erc20::{IFreeMintDispatcher, IFreeMintDispatcherTrait}; use ark_tokens::erc721::IFreeMintDispatcher as Erc721Dispatcher; use ark_tokens::erc721::IFreeMintDispatcherTrait as Erc721DispatcherTrait; -use snforge_std as snf; -use snf::{ContractClass, ContractClassTrait, CheatTarget}; - -use super::super::common::setup::{setup, setup_order}; - -fn create_offer_order( - executor_address: ContractAddress, - erc20_address: ContractAddress, - nft_address: ContractAddress, - token_id: u256 -) -> (felt252, ContractAddress, u256) { - let offerer = contract_address_const::<'offerer'>(); - let start_amount = 10_000_000; - - IFreeMintDispatcher { contract_address: erc20_address }.mint(offerer, start_amount); - - let mut order = setup_order(erc20_address, nft_address); - order.offerer = offerer; - order.start_amount = start_amount; - order.token_id = Option::Some(token_id); - - snf::start_prank(CheatTarget::One(executor_address), offerer); - IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); - - (order.compute_order_hash(), offerer, start_amount) -} - -fn create_collection_offer_order( - executor_address: ContractAddress, erc20_address: ContractAddress, nft_address: ContractAddress, -) -> (felt252, ContractAddress, u256) { - let offerer = contract_address_const::<'offerer'>(); - let start_amount = 10_000_000; - - IFreeMintDispatcher { contract_address: erc20_address }.mint(offerer, start_amount); - - let mut order = setup_order(erc20_address, nft_address); - order.offerer = offerer; - order.start_amount = start_amount; - order.token_id = Option::None; - - snf::start_prank(CheatTarget::One(executor_address), offerer); - IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); - - (order.compute_order_hash(), offerer, start_amount) -} - -fn create_listing_order( - executor_address: ContractAddress, - erc20_address: ContractAddress, - nft_address: ContractAddress, - start_amount: u256 -) -> (felt252, ContractAddress, u256) { - let offerer = contract_address_const::<'offerer'>(); - - let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } - .get_current_token_id() - .into(); - Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); - - let mut order = setup_order(erc20_address, nft_address); - order.route = RouteType::Erc721ToErc20.into(); - order.offerer = offerer; - order.token_id = Option::Some(token_id); - order.start_amount = start_amount; - - snf::start_prank(CheatTarget::One(executor_address), offerer); - IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); - - (order.compute_order_hash(), offerer, token_id) -} - -fn create_auction_order( - executor_address: ContractAddress, - erc20_address: ContractAddress, - nft_address: ContractAddress, - start_amount: u256, - end_amount: u256 -) -> (felt252, ContractAddress, u256) { - let offerer = contract_address_const::<'offerer'>(); - - let token_id: u256 = Erc721Dispatcher { contract_address: nft_address } - .get_current_token_id() - .into(); - Erc721Dispatcher { contract_address: nft_address }.mint(offerer, 'base_uri'); +use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; +use openzeppelin::token::erc721::interface::{IERC721Dispatcher, IERC721DispatcherTrait}; - let mut order = setup_order(erc20_address, nft_address); - order.route = RouteType::Erc721ToErc20.into(); - order.offerer = offerer; - order.token_id = Option::Some(token_id); - order.start_amount = start_amount; - order.end_amount = end_amount; +use snforge_std::{cheat_caller_address, CheatSpan}; +use starknet::{ContractAddress, contract_address_const}; - snf::start_prank(CheatTarget::One(executor_address), offerer); - IExecutorDispatcher { contract_address: executor_address }.create_order(order); - snf::stop_prank(CheatTarget::One(executor_address)); +use super::super::common::setup::{ + create_auction_order, create_collection_offer_order, create_listing_order, create_offer_order, + setup, setup_default_order, setup_auction_order, setup_collection_offer_order, + setup_listing_order, setup_offer_order, create_offer_order_erc1155, setup_erc1155 +}; - (order.compute_order_hash(), offerer, token_id) -} fn create_fulfill_info( order_hash: felt252, fulfiller: ContractAddress, token_address: ContractAddress, token_id: u256 @@ -127,6 +36,26 @@ fn create_fulfill_info( token_chain_id: 'SN_MAIN', token_address: token_address, token_id: Option::Some(token_id), + quantity: 1_u256, + fulfill_broker_address: contract_address_const::<'broker'>() + } +} + +fn create_fulfill_info_erc1155( + order_hash: felt252, + fulfiller: ContractAddress, + token_address: ContractAddress, + token_id: u256, + quantity: u256 +) -> FulfillInfo { + FulfillInfo { + order_hash: order_hash, + related_order_hash: Option::None, + fulfiller: fulfiller, + token_chain_id: 'SN_MAIN', + token_address: token_address, + token_id: Option::Some(token_id), + quantity: quantity, fulfill_broker_address: contract_address_const::<'broker'>() } } @@ -144,20 +73,17 @@ fn test_fulfill_offer_order_ok() { executor_address, erc20_address, nft_address, token_id ); - snf::start_prank(CheatTarget::One(erc20_address), offerer); + cheat_caller_address(erc20_address, offerer, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(nft_address), fulfiller); + cheat_caller_address(nft_address, fulfiller, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] @@ -172,24 +98,21 @@ fn test_fulfill_listing_order_ok() { IFreeMintDispatcher { contract_address: erc20_address }.mint(fulfiller, start_amount); - snf::start_prank(CheatTarget::One(nft_address), offerer); + cheat_caller_address(nft_address, offerer, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(erc20_address), fulfiller); + cheat_caller_address(erc20_address, fulfiller, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Caller is not the fulfiller",))] +#[should_panic(expected: "Caller is not the fulfiller")] fn test_fulfill_order_fulfiller_shall_be_caller() { let (executor_address, _erc20_address, nft_address) = setup(); let caller = contract_address_const::<'caller'>(); @@ -197,13 +120,12 @@ fn test_fulfill_order_fulfiller_shall_be_caller() { let fulfill_info = create_fulfill_info(0x123, fulfiller, nft_address, 1); - snf::start_prank(CheatTarget::One(executor_address), caller); + cheat_caller_address(executor_address, caller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Fulfiller does not own enough ERC20 tokens",))] +#[should_panic(expected: "Fulfiller does not own enough ERC20 tokens")] fn test_fulfill_listing_order_fulfiller_not_enough_erc20_token() { let (executor_address, erc20_address, nft_address) = setup(); let fulfiller = contract_address_const::<'fulfiller'>(); @@ -217,14 +139,13 @@ fn test_fulfill_listing_order_fulfiller_not_enough_erc20_token() { let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Fulfiller does not own the specified ERC721 token",))] -fn test_fulfill_offer_order_fulfiller_not_owner() { +#[should_panic(expected: "Fulfiller does not own the specified ERC721 token")] +fn test_fulfill_offer_order_fulfiller_not_owner_for_erc721() { let (executor_address, erc20_address, nft_address) = setup(); let fulfiller = contract_address_const::<'fulfiller'>(); let other = contract_address_const::<'other'>(); @@ -239,26 +160,46 @@ fn test_fulfill_offer_order_fulfiller_not_owner() { let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); + IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); +} + +#[test] +#[should_panic(expected: "Fulfiller does not own the specified amount of ERC1155 token")] +fn test_fulfill_offer_order_fulfiller_not_owner_for_erc1155() { + let (executor_address, erc20_address, erc1155_address) = setup_erc1155(); + let fulfiller = contract_address_const::<'fulfiller'>(); + let other = erc1155_address; + let quantity = 50_u256; + + let token_id = Erc1155Dispatcher { contract_address: erc1155_address }.mint(other, quantity); + + let (order_hash, _, _) = create_offer_order_erc1155( + executor_address, erc20_address, erc1155_address, token_id, quantity + ); + + let fulfill_info = create_fulfill_info_erc1155( + order_hash, fulfiller, erc1155_address, token_id, quantity + ); + + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Order not found",))] +#[should_panic(expected: 'OB: order not found')] fn test_fulfill_order_not_found() { let (executor_address, _erc20_address, nft_address) = setup(); let fulfiller = contract_address_const::<'fulfiller'>(); let fulfill_info = create_fulfill_info(0x1234, fulfiller, nft_address, 1); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Offerer's allowance of executor is not enough",))] +#[should_panic(expected: "Offerer's allowance of executor is not enough")] fn test_fulfill_offer_order_offerer_not_enough_allowance() { let (executor_address, erc20_address, nft_address) = setup(); let fulfiller = contract_address_const::<'fulfiller'>(); @@ -271,25 +212,22 @@ fn test_fulfill_offer_order_offerer_not_enough_allowance() { executor_address, erc20_address, nft_address, token_id ); - snf::start_prank(CheatTarget::One(erc20_address), offerer); + cheat_caller_address(erc20_address, offerer, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address } .approve(executor_address, start_amount - 10); - snf::stop_prank(CheatTarget::One(erc20_address)); let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(nft_address), fulfiller); + cheat_caller_address(nft_address, fulfiller, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Fulfiller's allowance of executor is not enough",))] +#[should_panic(expected: "Fulfiller's allowance of executor is not enough")] fn test_fulfill_listing_order_fulfiller_not_enough_allowance() { let (executor_address, erc20_address, nft_address) = setup(); let fulfiller = contract_address_const::<'fulfiller'>(); @@ -301,25 +239,22 @@ fn test_fulfill_listing_order_fulfiller_not_enough_allowance() { IFreeMintDispatcher { contract_address: erc20_address }.mint(fulfiller, start_amount); - snf::start_prank(CheatTarget::One(nft_address), offerer); + cheat_caller_address(nft_address, offerer, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(erc20_address), fulfiller); + cheat_caller_address(erc20_address, fulfiller, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address } .approve(executor_address, start_amount - 10); - snf::stop_prank(CheatTarget::One(erc20_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Executor not approved by offerer",))] +#[should_panic(expected: "Executor not approved by offerer")] fn test_fulfill_listing_order_offerer_not_approved() { let (executor_address, erc20_address, nft_address) = setup(); let fulfiller = contract_address_const::<'fulfiller'>(); @@ -333,17 +268,15 @@ fn test_fulfill_listing_order_offerer_not_approved() { let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(erc20_address), fulfiller); + cheat_caller_address(erc20_address, fulfiller, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Executor not approved by fulfiller",))] +#[should_panic(expected: "Executor not approved by fulfiller")] fn test_fulfill_offer_order_fulfiller_not_approved() { let (executor_address, erc20_address, nft_address) = setup(); let fulfiller = contract_address_const::<'fulfiller'>(); @@ -356,20 +289,18 @@ fn test_fulfill_offer_order_fulfiller_not_approved() { executor_address, erc20_address, nft_address, token_id ); - snf::start_prank(CheatTarget::One(erc20_address), offerer); + cheat_caller_address(erc20_address, offerer, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Offerer and fulfiller must be different",))] +#[should_panic(expected: "Offerer and fulfiller must be different")] fn test_fulfill_offer_order_fulfiller_same_as_offerer() { let (executor_address, erc20_address, nft_address) = setup(); @@ -382,24 +313,21 @@ fn test_fulfill_offer_order_fulfiller_same_as_offerer() { let fulfiller = offerer; Erc721Dispatcher { contract_address: nft_address }.mint(fulfiller, 'base_uri'); - snf::start_prank(CheatTarget::One(erc20_address), offerer); + cheat_caller_address(erc20_address, offerer, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(nft_address), fulfiller); + cheat_caller_address(nft_address, fulfiller, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ("Offerer and fulfiller must be different",))] +#[should_panic(expected: "Offerer and fulfiller must be different")] fn test_fulfill_listing_order_fulfiller_same_as_offerer() { let (executor_address, erc20_address, nft_address) = setup(); let start_amount = 10_000_000; @@ -411,20 +339,17 @@ fn test_fulfill_listing_order_fulfiller_same_as_offerer() { IFreeMintDispatcher { contract_address: erc20_address }.mint(fulfiller, start_amount); - snf::start_prank(CheatTarget::One(nft_address), offerer); + cheat_caller_address(nft_address, offerer, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(erc20_address), fulfiller); + cheat_caller_address(erc20_address, fulfiller, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] @@ -437,34 +362,27 @@ fn test_fulfill_auction_order_ok() { let (order_hash, offerer, token_id) = create_auction_order( executor_address, erc20_address, nft_address, start_amount, end_amount ); - let fulfiller = contract_address_const::<'fulfiller'>(); + let fulfiller = offerer; IFreeMintDispatcher { contract_address: erc20_address }.mint(buyer, start_amount); - let mut buyer_order = setup_order(erc20_address, nft_address); - buyer_order.offerer = buyer; - buyer_order.start_amount = start_amount; - buyer_order.token_id = Option::Some(token_id); + let buyer_order = setup_offer_order(erc20_address, nft_address, buyer, token_id, start_amount); - snf::start_prank(CheatTarget::One(executor_address), buyer); + cheat_caller_address(executor_address, buyer, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.create_order(buyer_order); - snf::stop_prank(CheatTarget::One(executor_address)); - snf::start_prank(CheatTarget::One(nft_address), offerer); + cheat_caller_address(nft_address, offerer, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); let mut fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); fulfill_info.related_order_hash = Option::Some(buyer_order.compute_order_hash()); - snf::start_prank(CheatTarget::One(erc20_address), buyer); + cheat_caller_address(erc20_address, buyer, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] @@ -481,34 +399,27 @@ fn test_fulfill_auction_order_fulfiller_same_as_offerer() { IFreeMintDispatcher { contract_address: erc20_address }.mint(buyer, start_amount); - let mut buyer_order = setup_order(erc20_address, nft_address); - buyer_order.offerer = buyer; - buyer_order.start_amount = start_amount; - buyer_order.token_id = Option::Some(token_id); + let buyer_order = setup_offer_order(erc20_address, nft_address, buyer, token_id, start_amount); - snf::start_prank(CheatTarget::One(executor_address), buyer); + cheat_caller_address(executor_address, buyer, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.create_order(buyer_order); - snf::stop_prank(CheatTarget::One(executor_address)); - snf::start_prank(CheatTarget::One(nft_address), offerer); + cheat_caller_address(nft_address, offerer, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); let mut fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); fulfill_info.related_order_hash = Option::Some(buyer_order.compute_order_hash()); - snf::start_prank(CheatTarget::One(erc20_address), buyer); + cheat_caller_address(erc20_address, buyer, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } #[test] -#[should_panic(expected: ('Executor not enabled',))] +#[should_panic(expected: 'Executor not enabled')] fn test_fulfill_order_not_enabled() { let (executor_address, erc20_address, nft_address) = setup(); let admin = contract_address_const::<'admin'>(); @@ -522,22 +433,18 @@ fn test_fulfill_order_not_enabled() { executor_address, erc20_address, nft_address, token_id ); - snf::start_prank(CheatTarget::One(erc20_address), offerer); + cheat_caller_address(erc20_address, offerer, CheatSpan::TargetCalls(1)); IERC20Dispatcher { contract_address: erc20_address }.approve(executor_address, start_amount); - snf::stop_prank(CheatTarget::One(erc20_address)); let fulfill_info = create_fulfill_info(order_hash, fulfiller, nft_address, token_id); - snf::start_prank(CheatTarget::One(nft_address), fulfiller); + cheat_caller_address(nft_address, fulfiller, CheatSpan::TargetCalls(1)); IERC721Dispatcher { contract_address: nft_address } .set_approval_for_all(executor_address, true); - snf::stop_prank(CheatTarget::One(nft_address)); - snf::start_prank(CheatTarget::One(executor_address), admin); + cheat_caller_address(executor_address, admin, CheatSpan::TargetCalls(1)); IMaintenanceDispatcher { contract_address: executor_address }.set_maintenance_mode(true); - snf::stop_prank(CheatTarget::One(executor_address)); - snf::start_prank(CheatTarget::One(executor_address), fulfiller); + cheat_caller_address(executor_address, fulfiller, CheatSpan::TargetCalls(1)); IExecutorDispatcher { contract_address: executor_address }.fulfill_order(fulfill_info); - snf::stop_prank(CheatTarget::One(executor_address)); } diff --git a/contracts/ark_starknet/tests/integration/maintenance.cairo b/contracts/ark_starknet/tests/integration/maintenance.cairo index 4f3e7160e..4f74e3ce8 100644 --- a/contracts/ark_starknet/tests/integration/maintenance.cairo +++ b/contracts/ark_starknet/tests/integration/maintenance.cairo @@ -1,10 +1,11 @@ -use starknet::{ContractAddress, contract_address_const}; -use ark_starknet::interfaces::{IMaintenanceDispatcher, IMaintenanceDispatcherTrait}; use ark_starknet::executor::executor; +use ark_starknet::interfaces::{IMaintenanceDispatcher, IMaintenanceDispatcherTrait}; -use snforge_std as snf; -use snf::cheatcodes::events::{EventFetcher, EventAssertions}; -use snf::{ContractClass, ContractClassTrait, CheatTarget, spy_events, SpyOn}; +use snforge_std::{ + ContractClass, ContractClassTrait, cheat_caller_address, CheatSpan, spy_events, + EventSpyAssertionsTrait, +}; +use starknet::{ContractAddress, contract_address_const}; use super::super::common::setup::deploy_executor; @@ -13,8 +14,10 @@ fn admin_can_change_executor_state() { let admin = contract_address_const::<'admin'>(); let executor_address = deploy_executor(); let executor = IMaintenanceDispatcher { contract_address: executor_address }; - let mut spy = spy_events(SpyOn::One(executor_address)); - snf::start_prank(snf::CheatTarget::One(executor_address), admin); + + let mut spy = spy_events(); + + cheat_caller_address(executor_address, admin, CheatSpan::TargetCalls(1)); executor.set_maintenance_mode(true); assert!(executor.is_in_maintenance(), "Executor should be in maintenance"); spy @@ -28,7 +31,8 @@ fn admin_can_change_executor_state() { ) ] ); - + let mut spy = spy_events(); + cheat_caller_address(executor_address, admin, CheatSpan::TargetCalls(1)); executor.set_maintenance_mode(false); assert!(!executor.is_in_maintenance(), "Executor should not be in maintenance"); spy @@ -42,8 +46,6 @@ fn admin_can_change_executor_state() { ) ] ); - - snf::stop_prank(snf::CheatTarget::One(executor_address)); } #[test] @@ -52,9 +54,8 @@ fn only_admin_can_change_disable_executor() { let executor_address = deploy_executor(); let alice = contract_address_const::<'alice'>(); - snf::start_prank(snf::CheatTarget::One(executor_address), alice); + cheat_caller_address(executor_address, alice, CheatSpan::TargetCalls(1)); IMaintenanceDispatcher { contract_address: executor_address }.set_maintenance_mode(true); - snf::stop_prank(snf::CheatTarget::One(executor_address)); } #[test] @@ -63,7 +64,6 @@ fn only_admin_can_change_enable_executor() { let executor_address = deploy_executor(); let alice = contract_address_const::<'alice'>(); - snf::start_prank(snf::CheatTarget::One(executor_address), alice); + cheat_caller_address(executor_address, alice, CheatSpan::TargetCalls(1)); IMaintenanceDispatcher { contract_address: executor_address }.set_maintenance_mode(false); - snf::stop_prank(snf::CheatTarget::One(executor_address)); } diff --git a/contracts/ark_starknet/tests/lib.cairo b/contracts/ark_starknet/tests/lib.cairo index 9b47e3f91..c575397ce 100644 --- a/contracts/ark_starknet/tests/lib.cairo +++ b/contracts/ark_starknet/tests/lib.cairo @@ -6,8 +6,9 @@ mod unit { mod test_fees; } mod integration { + mod cancel_order; mod create_order; - mod execute_order; + // mod execute_order; mod fees_amount; mod fulfill_order; mod maintenance; diff --git a/contracts/ark_starknet/tests/unit/test_fees.cairo b/contracts/ark_starknet/tests/unit/test_fees.cairo index 55ba5321b..dfa1e2ae1 100644 --- a/contracts/ark_starknet/tests/unit/test_fees.cairo +++ b/contracts/ark_starknet/tests/unit/test_fees.cairo @@ -1,10 +1,12 @@ use ark_starknet::executor::{executor}; use ark_starknet::interfaces::FeesRatio; -use starknet::{ContractAddress}; +use snforge_std::{ + start_cheat_caller_address_global, stop_cheat_caller_address_global, test_address +}; use starknet::testing; -use snforge_std as snf; +use starknet::{ContractAddress}; #[test] fn test_add_broker() { @@ -12,15 +14,16 @@ fn test_add_broker() { let fees_ratio = FeesRatio { numerator: 10, denominator: 100, }; - let broker_address = snf::test_address(); + let broker_address = test_address(); // Call the add_broker method. - snf::start_prank(snf::CheatTarget::All, broker_address); + start_cheat_caller_address_global(broker_address); executor::ExecutorImpl::set_broker_fees(ref state, fees_ratio); let result = executor::ExecutorImpl::get_broker_fees(@state, broker_address); assert(result == fees_ratio, 'Fees are not equal'); + stop_cheat_caller_address_global(); } #[test] @@ -43,9 +46,10 @@ fn test_fees_ratio_bigger_than_1_broker_fees() { let fees_ratio = FeesRatio { numerator: 500, denominator: 100, }; - let broker_address = snf::test_address(); - snf::start_prank(snf::CheatTarget::All, broker_address); + let broker_address = test_address(); + start_cheat_caller_address_global(broker_address); executor::ExecutorImpl::set_broker_fees(ref state, fees_ratio); + stop_cheat_caller_address_global(); } #[test] @@ -65,9 +69,10 @@ fn test_fees_denominator_0_broker_fees() { let fees_ratio = FeesRatio { numerator: 10, denominator: 0, }; - let broker_address = snf::test_address(); - snf::start_prank(snf::CheatTarget::All, broker_address); + let broker_address = test_address(); + start_cheat_caller_address_global(broker_address); executor::ExecutorImpl::set_broker_fees(ref state, fees_ratio); + stop_cheat_caller_address_global(); } #[test] diff --git a/contracts/ark_tokens/Scarb.toml b/contracts/ark_tokens/Scarb.toml index 862324da4..cc8305bee 100644 --- a/contracts/ark_tokens/Scarb.toml +++ b/contracts/ark_tokens/Scarb.toml @@ -4,11 +4,16 @@ description = "StarkNet contracts for test tokens" version = "0.1.0" [dependencies] -starknet = "2.5.4" -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.18.0" } -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.10.0" } +starknet.workspace = true +openzeppelin.workspace = true ark_oz = { path = "../ark_oz" } +[dev-dependencies] +snforge_std.workspace = true + +[tool] +fmt.workspace = true + [lib] [[target.starknet-contract]] diff --git a/contracts/ark_tokens/src/erc1155.cairo b/contracts/ark_tokens/src/erc1155.cairo new file mode 100644 index 000000000..ab6744b68 --- /dev/null +++ b/contracts/ark_tokens/src/erc1155.cairo @@ -0,0 +1,88 @@ +use starknet::ContractAddress; + +#[starknet::interface] +trait IFreeMint { + fn mint(ref self: T, recipient: ContractAddress, value: u256) -> u256; + fn get_current_token_id(self: @T) -> felt252; +} + +#[starknet::contract] +mod FreeMintERC1155 { + use openzeppelin::introspection::src5::SRC5Component; + use openzeppelin::token::erc1155::ERC1155Component; + use openzeppelin::token::erc1155::ERC1155HooksEmptyImpl; + use openzeppelin::token::erc1155::ERC1155ReceiverComponent; + use starknet::ContractAddress; + use super::IFreeMint; + + component!(path: ERC1155Component, storage: erc1155, event: ERC1155Event); + component!( + path: ERC1155ReceiverComponent, storage: erc1155_receiver, event: ERC1155ReceiverEvent + ); + component!(path: SRC5Component, storage: src5, event: SRC5Event); + + // Externals + #[abi(embed_v0)] + impl ERC1155Impl = ERC1155Component::ERC1155Impl; + #[abi(embed_v0)] + impl ERC1155ReceiverImpl = + ERC1155ReceiverComponent::ERC1155ReceiverImpl; + #[abi(embed_v0)] + impl SRC5Impl = SRC5Component::SRC5Impl; + + // Internal impl + impl ERC1155InternalImpl = ERC1155Component::InternalImpl; + impl ERC1155ReceiverInternalImpl = ERC1155ReceiverComponent::InternalImpl; + + + #[storage] + struct Storage { + #[substorage(v0)] + erc1155: ERC1155Component::Storage, + #[substorage(v0)] + erc1155_receiver: ERC1155ReceiverComponent::Storage, + #[substorage(v0)] + src5: SRC5Component::Storage, + latest_token_id: u256 + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + #[flat] + ERC1155Event: ERC1155Component::Event, + #[flat] + ERC1155ReceiverEvent: ERC1155ReceiverComponent::Event, + #[flat] + SRC5Event: SRC5Component::Event + } + + #[constructor] + fn constructor(ref self: ContractState, base_uri: ByteArray) { + self.erc1155.initializer(base_uri); + self.erc1155_receiver.initializer(); + self.latest_token_id.write(1); + } + + #[abi(embed_v0)] + impl ImplFreeMint of IFreeMint { + fn get_current_token_id(self: @ContractState) -> felt252 { + self.latest_token_id.read().try_into().unwrap() + } + + fn mint(ref self: ContractState, recipient: ContractAddress, value: u256) -> u256 { + let token_id = self.latest_token_id.read(); + self._mint(recipient, token_id, value); + self.latest_token_id.write(token_id + 1); + token_id + } + } + + + #[generate_trait] + impl InternalImpl of InternalTrait { + fn _mint(ref self: ContractState, to: ContractAddress, token_id: u256, value: u256) { + self.erc1155.mint_with_acceptance_check(to, token_id, value, array![].span()); + } + } +} diff --git a/contracts/ark_tokens/src/erc20.cairo b/contracts/ark_tokens/src/erc20.cairo index 974f2cc5b..b8a04fbc8 100644 --- a/contracts/ark_tokens/src/erc20.cairo +++ b/contracts/ark_tokens/src/erc20.cairo @@ -8,6 +8,7 @@ trait IFreeMint { #[starknet::contract] mod FreeMintERC20 { use openzeppelin::token::erc20::ERC20Component; + use openzeppelin::token::erc20::ERC20HooksEmptyImpl; use starknet::ContractAddress; use super::IFreeMint; @@ -47,7 +48,7 @@ mod FreeMintERC20 { #[abi(embed_v0)] impl ImplFreeMint of IFreeMint { fn mint(ref self: ContractState, recipient: ContractAddress, amount: u256) { - self.erc20._mint(recipient, amount); + self.erc20.mint(recipient, amount); } } } diff --git a/contracts/ark_tokens/src/erc721.cairo b/contracts/ark_tokens/src/erc721.cairo index 930807baf..53e860d9e 100644 --- a/contracts/ark_tokens/src/erc721.cairo +++ b/contracts/ark_tokens/src/erc721.cairo @@ -8,14 +8,15 @@ trait IFreeMint { #[starknet::contract] mod FreeMintNFT { + use core::array::ArrayTrait; + use core::serde::Serde; + use core::traits::Into; + use core::traits::TryInto; use openzeppelin::introspection::src5::SRC5Component; use openzeppelin::token::erc721::ERC721Component; + use openzeppelin::token::erc721::ERC721HooksEmptyImpl; use starknet::ContractAddress; - use core::traits::Into; - use core::serde::Serde; - use core::traits::TryInto; use super::IFreeMint; - use core::array::ArrayTrait; component!(path: ERC721Component, storage: erc721, event: ERC721Event); component!(path: SRC5Component, storage: src5, event: SRC5Event); @@ -66,7 +67,7 @@ mod FreeMintNFT { fn mint(ref self: ContractState, recipient: ContractAddress, token_uri: felt252) { let token_id = self.latest_token_id.read(); - self.erc721._mint(recipient, token_id); + self.erc721.mint(recipient, token_id); self.latest_token_id.write(token_id + 1); } } diff --git a/contracts/ark_tokens/src/erc721_royalty.cairo b/contracts/ark_tokens/src/erc721_royalty.cairo index 8aa3d1c8f..15e258801 100644 --- a/contracts/ark_tokens/src/erc721_royalty.cairo +++ b/contracts/ark_tokens/src/erc721_royalty.cairo @@ -8,18 +8,18 @@ trait IFreeMint { #[starknet::contract] mod FreeMintNFTRoyalty { - use starknet::ContractAddress; - use core::traits::Into; + use ark_oz::erc2981::ERC2981Component; + use ark_oz::erc2981::FeesRatioDefault; + use core::array::ArrayTrait; use core::serde::Serde; + use core::traits::Into; use core::traits::TryInto; - use core::array::ArrayTrait; + use openzeppelin::access::ownable::OwnableComponent; use openzeppelin::introspection::src5::SRC5Component; use openzeppelin::token::erc721::ERC721Component; - use openzeppelin::access::ownable::OwnableComponent; - - use ark_oz::erc2981::ERC2981Component; - use ark_oz::erc2981::FeesRatioDefault; + use openzeppelin::token::erc721::ERC721HooksEmptyImpl; + use starknet::ContractAddress; use super::IFreeMint; @@ -93,7 +93,7 @@ mod FreeMintNFTRoyalty { fn mint(ref self: ContractState, recipient: ContractAddress, token_uri: felt252) { let token_id = self.latest_token_id.read(); - self.erc721._mint(recipient, token_id); + self.erc721.mint(recipient, token_id); self.latest_token_id.write(token_id + 1); } } diff --git a/contracts/ark_tokens/src/lib.cairo b/contracts/ark_tokens/src/lib.cairo index 5e9a35100..a0c97edf3 100644 --- a/contracts/ark_tokens/src/lib.cairo +++ b/contracts/ark_tokens/src/lib.cairo @@ -1,4 +1,5 @@ +mod erc1155; +mod erc20; mod erc721; mod erc721_royalty; -mod erc20; diff --git a/contracts/solis/Makefile b/contracts/solis/Makefile deleted file mode 100644 index 0d6c6d828..000000000 --- a/contracts/solis/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -generate_artifacts: - scarb build - mkdir -p ../../../artifacts - jq .abi ./target/dev/solis_starknet_utils.contract_class.json > ../../../artifacts/starknet_utils.json diff --git a/contracts/solis/Scarb.lock b/contracts/solis/Scarb.lock deleted file mode 100644 index ba780bd80..000000000 --- a/contracts/solis/Scarb.lock +++ /dev/null @@ -1,6 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "solis" -version = "0.1.0" diff --git a/contracts/solis/Scarb.toml b/contracts/solis/Scarb.toml deleted file mode 100644 index a9563e13b..000000000 --- a/contracts/solis/Scarb.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "solis" -version = "0.1.0" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html - -[dependencies] -starknet = "2.5.4" - -[[target.starknet-contract]] -sierra = true -casm = true diff --git a/contracts/solis/src/lib.cairo b/contracts/solis/src/lib.cairo deleted file mode 100644 index 6dff9cab0..000000000 --- a/contracts/solis/src/lib.cairo +++ /dev/null @@ -1 +0,0 @@ -mod starknet_utils; diff --git a/contracts/solis/src/starknet_utils.cairo b/contracts/solis/src/starknet_utils.cairo deleted file mode 100644 index 39d56256a..000000000 --- a/contracts/solis/src/starknet_utils.cairo +++ /dev/null @@ -1,49 +0,0 @@ -//! Starknet utils contract, to generate -//! and ABI usable by Solis to interact with -//! starknet. -#[starknet::contract] -mod starknet_utils { - use starknet::ContractAddress; - - #[storage] - struct Storage {} - - #[abi(embed_v0)] - fn owner_of(self: @ContractState, token_id: u256) -> ContractAddress { - 0.try_into().unwrap() - } - - #[abi(embed_v0)] - fn ownerOf(self: @ContractState, token_id: u256) -> ContractAddress { - 0.try_into().unwrap() - } - - #[abi(embed_v0)] - fn is_approved_for_all( - self: @ContractState, owner: ContractAddress, operator: ContractAddress - ) -> bool { - false - } - - #[abi(embed_v0)] - fn isApprovedForAll( - self: @ContractState, owner: ContractAddress, operator: ContractAddress - ) -> bool { - false - } - - #[abi(embed_v0)] - fn is_valid_signature(self: @ContractState, hash: felt252, signature: Span) -> bool { - false - } - - #[abi(embed_v0)] - fn balanceOf(self: @ContractState, account: ContractAddress) -> u256 { - 0_u256 - } - - #[abi(embed_v0)] - fn allowance(self: @ContractState, owner: ContractAddress, spender: ContractAddress) -> u256 { - 0_u256 - } -} diff --git a/crates/ark-metadata/src/metadata_manager.rs b/crates/ark-metadata/src/metadata_manager.rs index 07f9bcf74..9eb3fac98 100644 --- a/crates/ark-metadata/src/metadata_manager.rs +++ b/crates/ark-metadata/src/metadata_manager.rs @@ -119,6 +119,7 @@ impl<'a, T: Storage, C: StarknetClient, F: FileManager, E: ElasticsearchManager> ipfs_gateway_uri, image_timeout, request_referrer, + contract_address, ) .await .map_err(|err| MetadataError::RequestTokenUriError(err.to_string()))?; diff --git a/crates/ark-metadata/src/utils.rs b/crates/ark-metadata/src/utils.rs index f935cf572..bd7c5c5e7 100644 --- a/crates/ark-metadata/src/utils.rs +++ b/crates/ark-metadata/src/utils.rs @@ -12,12 +12,31 @@ use std::str::FromStr; use std::time::Duration; use tracing::{debug, error, trace, warn}; +pub fn normalize_onchain_data(contract_address: &str, uri: &str) -> String { + let mut normalized = uri.replace("https://gateway.pinata.cloud/ipfs/", "ipfs://"); + + // This is a workaround to handle the invalid JSON format specific to the Loot Survivor: Beasts collection. + // The original JSON contains some improperly formatted quotes that need correction + // for proper parsing. This normalization is tailored specifically to fix those issues. + + // Loot Survivor: Beasts + if contract_address == "0x0158160018d590d93528995b340260e65aedd76d28a686e9daa5c4e8fad0c5dd" { + normalized = normalized.replace("%20", " ").replace(":\"\"", ":\""); + normalized = ('A'..='Z').fold(normalized, |acc, c| { + acc.replace(&format!("\" {}", c), &format!(" {}", c)) + }); + } + + normalized +} + pub async fn get_token_metadata( client: &Client, uri: &str, ipfs_gateway_uri: &str, request_timeout_duration: Duration, request_referrer: &str, + contract_address: &str, ) -> Result { let parsed_uri = uri.replace("https://gateway.pinata.cloud/ipfs/", "ipfs://"); let metadata_type = get_metadata_type(parsed_uri.as_str()); @@ -40,7 +59,7 @@ pub async fn get_token_metadata( } MetadataType::OnChain(uri) => { trace!("Fetching on-chain metadata: {}", uri); - fetch_onchain_metadata(&uri)? + fetch_onchain_metadata(contract_address, &uri)? } }; Ok(metadata) @@ -171,8 +190,10 @@ pub fn get_content_type_from_extension(extension: &str) -> &str { } } -fn fetch_onchain_metadata(uri: &str) -> Result { - let uri_string = urlencoding::decode(uri) +fn fetch_onchain_metadata(contract_address: &str, uri: &str) -> Result { + let parsed_uri = normalize_onchain_data(contract_address, uri); + + let uri_string = urlencoding::decode(parsed_uri.as_str()) .map(|s| s.into_owned()) .unwrap_or_else(|_| uri.to_string()); @@ -451,8 +472,8 @@ mod tests { .to_string(); let encoded_metadata = base64_encode(&metadata_json); let uri = format!("data:application/json;base64,{}", encoded_metadata); - - let fetched_metadata = fetch_onchain_metadata(&uri).unwrap(); + let contract_address = "0x1234567890123456789012345678901234567890"; + let fetched_metadata = fetch_onchain_metadata(contract_address, &uri).unwrap(); assert_eq!(fetched_metadata.raw, metadata_json); assert_eq!( @@ -471,8 +492,8 @@ mod tests { }) .to_string(); let uri = format!("data:application/json,{}", metadata_json); - - let fetched_metadata = fetch_onchain_metadata(&uri).unwrap(); + let contract_address = "0x1234567890123456789012345678901234567890"; + let fetched_metadata = fetch_onchain_metadata(contract_address, &uri).unwrap(); assert_eq!(fetched_metadata.raw, metadata_json); assert_eq!( @@ -484,10 +505,17 @@ mod tests { #[test] fn handle_invalid_onchain_metadata_format() { + let contract_address = "0x1234567890123456789012345678901234567890"; let invalid_uri = "data:application/json;utf8,invalid_json"; - - let result = fetch_onchain_metadata(invalid_uri); - + let result = fetch_onchain_metadata(contract_address, invalid_uri); assert!(result.is_err() || result.unwrap().normalized.name.is_none()); } + + #[test] + fn test_normalize_onchain_data() { + let contract_address = "0x0158160018d590d93528995b340260e65aedd76d28a686e9daa5c4e8fad0c5dd"; + let uri = r#"data:application/json;utf8,{"name":""Pandemonium%20Growl"%20Wyvern","description":"Beasts","attributes":[{"trait_type":"prefix","value":"Pandemonium"},{"trait_type":"name","value":"Wyvern"},{"trait_type":"suffix","value":"Growl"},{"trait_type":"type","value":"Hunter"},{"trait_type":"tier","value":3},{"trait_type":"level","value":115},{"trait_type":"health","value":511}],"image":"data:image/svg+xml;utf8,"}"#; + let normalized = normalize_onchain_data(contract_address, uri); + assert_eq!(normalized, "data:application/json;utf8,{\"name\":\"Pandemonium Growl Wyvern\",\"description\":\"Beasts\",\"attributes\":[{\"trait_type\":\"prefix\",\"value\":\"Pandemonium\"},{\"trait_type\":\"name\",\"value\":\"Wyvern\"},{\"trait_type\":\"suffix\",\"value\":\"Growl\"},{\"trait_type\":\"type\",\"value\":\"Hunter\"},{\"trait_type\":\"tier\",\"value\":3},{\"trait_type\":\"level\",\"value\":115},{\"trait_type\":\"health\",\"value\":511}],\"image\":\"data:image/svg+xml;utf8,\"}"); + } } diff --git a/crates/diri/Cargo.toml b/crates/diri/Cargo.toml index 093d45848..1e233e161 100644 --- a/crates/diri/Cargo.toml +++ b/crates/diri/Cargo.toml @@ -7,30 +7,40 @@ Diri is a library / binary related to the indexation of Solis data (orderbook smart contracts). """ +[lib] +path = "src/lib.rs" + +[[example]] +name = "display-events" +path = "examples/display-events.rs" + [dependencies] futures = "0.3.28" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive", "rc"] } serde_json = "1.0" # TODO: add more stuff to the workspace after merge. url = "2.3.1" -clap = { version = "4.3.19", features = ["derive", "env", "string"] } regex = "1.9.1" env_logger = "0.10.0" log = "0.4.17" -dotenv = "0.15.0" thiserror = "1.0.32" # For now, Diri can't use the ark-starknet due to the dependency # on ArkProjectNFTs for of starknet-rs. -starknet = "0.8.0" +starknet = "0.12.0" +starknet-types-core = "0.1.7" + tracing = "0.1" num-bigint = "0.4.4" -num-traits = "0.2.17" - -cainome = { git = "https://github.com/cartridge-gg/cainome", tag = "v0.1.8", features = [ - "abigen-rs", -] } +num-traits = "0.2.19" anyhow.workspace = true async-trait.workspace = true tokio.workspace = true + +orderbook = { path = "../orderbook" } + +[dev-dependencies] +clap = { version = "4.3.19", features = ["derive", "env", "string"] } +dotenv = "0.15.0" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } diff --git a/crates/diri/examples/display-events.rs b/crates/diri/examples/display-events.rs new file mode 100644 index 000000000..9b18fd3c1 --- /dev/null +++ b/crates/diri/examples/display-events.rs @@ -0,0 +1,473 @@ +use anyhow::Result; +use async_trait::async_trait; +use clap::Parser; +use diri::event_handler::EventHandler; +use diri::storage::types::CancelledData; +use diri::storage::types::ExecutedData; +use diri::storage::types::FulfilledData; +use diri::storage::types::PlacedData; +use diri::storage::types::RollbackStatusData; +use diri::storage::Storage; +use diri::storage::StorageResult; +use diri::Diri; +use dotenv::dotenv; +use serde::ser::SerializeStruct; +use serde::Serialize; +use starknet::core::types::BlockId; +use starknet::core::types::Felt; +use starknet::providers::jsonrpc::HttpTransport; +use starknet::providers::AnyProvider; +use starknet::providers::JsonRpcClient; +use starknet::providers::Provider; +use url::Url; + +use std::fs::File; +use std::sync::atomic::AtomicU64; +use std::sync::atomic::Ordering; +use std::sync::Arc; +use std::sync::Mutex; + +use tracing::{error, info, trace, warn}; +use tracing_subscriber::fmt; +use tracing_subscriber::EnvFilter; + +#[derive(Parser, Debug)] +#[clap(about = "display-events")] +struct Args { + #[clap(long, help = "Starknet RPC", env = "STARKNET_RPC")] + rpc: String, + + #[clap(long, help = "Sleep period in milliseconds", default_value = "500")] + sleep_msecs: u64, + + #[clap( + long, + help = "Starting block number", + env = "BLOCK_START", + default_value = "0" + )] + block_start: u64, + + #[clap(long, help = "Ending block number", env = "BLOCK_END")] + block_end: Option, + + #[clap(long, help = "Block range", env = "BLOCK_RANGE", default_value = "0")] + block_range: u64, + + #[clap(long, help = "Contract address", env = "CONTRACT_ADDRESS")] + contract: Option, + + #[clap(long, help = "Nb limit of retries")] + limit_wait_retries: Option, + + #[clap(long, help = "JSON output", env = "JSON_OUTPUT")] + output: Option, +} + +#[tokio::main] +async fn main() -> Result<()> { + dotenv().ok(); + + let args = Args::parse(); + + init_logging(); + + let rpc_url = args.rpc; + let rpc_url_converted = Url::parse(&rpc_url).unwrap(); + + let provider = Arc::new(AnyProvider::JsonRpcHttp(JsonRpcClient::new( + HttpTransport::new(rpc_url_converted.clone()), + ))); + + let sleep_msecs = args.sleep_msecs; + let mut from = args.block_start; + let range = args.block_range; + let contract_address = match args.contract { + Some(v) => match Felt::from_hex(&v) { + Ok(v) => Some(v), + Err(e) => { + error!("Failed to parse contract address: {}", e); + None + } + }, + None => None, + }; + + // Set to None to keep polling the head of chain. + let to = args.block_end; + let limit_wait_retries = args.limit_wait_retries; + let mut nb_retries = 0_u64; + + info!("Starting.....!"); + + let storage = Arc::new(JSONStorage::new(args.output, from)); + + let handler = DefaultEventHandler {}; + + let indexer = Arc::new(Diri::new( + provider.clone(), + storage.clone(), + Arc::new(handler), + )); + + info!( + "Starting arkchain indexer: from:{} to:{:?} range:{}", + from, to, range, + ); + + loop { + let latest_block = match provider.block_number().await { + Ok(block_number) => block_number, + Err(e) => { + error!("Can't get arkchain block number: {}", e); + tokio::time::sleep(tokio::time::Duration::from_millis(sleep_msecs)).await; + continue; + } + }; + + trace!("Latest block {latest_block} (from={from})"); + + let start = from; + let mut end = std::cmp::min(from + range, latest_block); + if let Some(to) = to { + if end > to { + end = to + } + } + + if start > end { + trace!("Nothing to fetch at block {start}"); + if let Some(limit_wait_retries) = limit_wait_retries { + if nb_retries > limit_wait_retries { + info!("Wait limit reached"); + storage.end.store(latest_block, Ordering::SeqCst); + break; + } + nb_retries += 1; + } + tokio::time::sleep(tokio::time::Duration::from_millis(sleep_msecs)).await; + continue; + } + nb_retries = 0; + trace!("Fetching blocks {start} - {end}"); + match indexer + .index_block_range( + BlockId::Number(start), + BlockId::Number(end), + contract_address, + ) + .await + { + Ok(_) => { + trace!("Blocks successfully indexed"); + + if let Some(to) = to { + if end >= to { + trace!("`to` block was reached, exit."); + storage.end.store(end, Ordering::SeqCst); + break; + } + } + + // +1 to not re-index the end block. + from = end + 1; + } + Err(e) => { + error!("Blocks indexing error: {}", e); + + // TODO: for now, any failure on the block range, we skip it. + // Can be changed as needed. + warn!("Skipping blocks range: {} - {}", start, end); + from = end + 1; + } + }; + + tokio::time::sleep(tokio::time::Duration::from_millis(sleep_msecs)).await; + } + storage.write(); + Ok(()) +} + +/// Initializes the logging, ensuring that the `RUST_LOG` environment +/// variable is always considered first. +fn init_logging() { + const DEFAULT_LOG_FILTER: &str = "info,diri=trace"; + + tracing::subscriber::set_global_default( + fmt::Subscriber::builder() + .with_env_filter( + EnvFilter::try_from_default_env() + .or(EnvFilter::try_new(DEFAULT_LOG_FILTER)) + .expect("Invalid RUST_LOG filters"), + ) + .finish(), + ) + .expect("Failed to set the global tracing subscriber"); +} + +#[derive(Clone, Debug)] +enum OrderbookEventType { + Placed(PlacedData), + Cancelled(CancelledData), + Fulfilled(FulfilledData), + Executed(ExecutedData), + RollbackStatus(RollbackStatusData), +} + +struct SerializablePlacedData(PlacedData); +struct SerializableCancelledData(CancelledData); +struct SerializableFulfilledData(FulfilledData); +struct SerializableExecutedData(ExecutedData); +struct SerializableRollbackStatus(RollbackStatusData); + +impl Serialize for SerializablePlacedData { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("data", 9)?; + state.serialize_field("order_hash", &self.0.order_hash)?; + state.serialize_field("order_type", &self.0.order_type)?; + state.serialize_field("broker_id", &self.0.broker_id)?; + state.serialize_field("offerer", &self.0.offerer)?; + state.serialize_field("token_address", &self.0.token_address)?; + state.serialize_field("token_id", &self.0.token_id)?; + state.serialize_field("quantity", &self.0.quantity)?; + state.serialize_field("start_amount", &self.0.start_amount)?; + state.serialize_field("end_amount", &self.0.end_amount)?; + state.end() + } +} + +impl Serialize for SerializableCancelledData { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("data", 3)?; + state.serialize_field("order_hash", &self.0.order_hash)?; + state.serialize_field("order_type", &self.0.order_type)?; + state.serialize_field("reason", &self.0.reason)?; + state.end() + } +} + +impl Serialize for SerializableFulfilledData { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("data", 4)?; + state.serialize_field("order_hash", &self.0.order_hash)?; + state.serialize_field("order_type", &self.0.order_type)?; + state.serialize_field("fulfiller", &self.0.fulfiller)?; + state.serialize_field("related_order_hash", &self.0.related_order_hash)?; + state.end() + } +} + +impl Serialize for SerializableExecutedData { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("data", 4)?; + state.serialize_field("order_hash", &self.0.order_hash)?; + state.serialize_field("order_type", &self.0.order_type)?; + state.serialize_field("from", &self.0.from)?; + state.serialize_field("to", &self.0.to)?; + state.end() + } +} + +impl Serialize for SerializableRollbackStatus { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("data", 3)?; + state.serialize_field("order_hash", &self.0.order_hash)?; + state.serialize_field("order_type", &self.0.order_type)?; + state.serialize_field("reason", &self.0.reason)?; + state.end() + } +} + +impl Serialize for OrderbookEventType { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let type_key = "type"; + let data_key = "data"; + + let mut state = serializer.serialize_struct("event", 2)?; + match self { + OrderbookEventType::Placed(data) => { + state.serialize_field(type_key, "PLACED")?; + state.serialize_field(data_key, &SerializablePlacedData(data.clone()))?; + } + OrderbookEventType::Cancelled(data) => { + state.serialize_field(type_key, "CANCELLED")?; + state.serialize_field(data_key, &SerializableCancelledData(data.clone()))?; + } + OrderbookEventType::Fulfilled(data) => { + state.serialize_field(type_key, "FULFILLED")?; + state.serialize_field(data_key, &SerializableFulfilledData(data.clone()))?; + } + OrderbookEventType::Executed(data) => { + state.serialize_field(type_key, "EXECUTED")?; + state.serialize_field(data_key, &SerializableExecutedData(data.clone()))?; + } + OrderbookEventType::RollbackStatus(data) => { + state.serialize_field(type_key, "ROLLBACK")?; + state.serialize_field(data_key, &SerializableRollbackStatus(data.clone()))?; + } + }; + state.end() + } +} + +#[derive(Clone, Serialize, Debug)] +struct OrderbookEvent { + #[serde(rename = "event")] + event_type: OrderbookEventType, + block_id: u64, + block_timestamp: u64, +} + +#[derive(Serialize, Debug)] +struct JSONStorage { + start: u64, + end: AtomicU64, + #[serde(skip)] + output: Option, + events: Mutex>, +} + +impl JSONStorage { + fn new(output: Option, start: u64) -> Self { + Self { + output, + start, + end: AtomicU64::new(0), + events: Mutex::new(Vec::new()), + } + } + + fn write(&self) { + if self.output.is_none() { + println!("{}", serde_json::to_string_pretty(self).unwrap()); + } else { + let mut file = File::create(self.output.clone().unwrap()).unwrap(); + serde_json::to_writer_pretty(&mut file, &self).unwrap(); + } + } +} + +#[async_trait] +impl Storage for JSONStorage { + async fn register_placed( + &self, + block_id: u64, + block_timestamp: u64, + order: &PlacedData, + ) -> StorageResult<()> { + trace!("PLACED {} {:?}", block_id, order); + if let Ok(mut events) = self.events.lock() { + events.push(OrderbookEvent { + block_id, + block_timestamp, + event_type: OrderbookEventType::Placed(order.clone()), + }); + } else { + error!("Failed to append Placed event"); + } + Ok(()) + } + + async fn register_cancelled( + &self, + block_id: u64, + block_timestamp: u64, + order: &CancelledData, + ) -> StorageResult<()> { + trace!("CANCELLED {} {:?}", block_id, order); + if let Ok(mut events) = self.events.lock() { + events.push(OrderbookEvent { + block_id, + block_timestamp, + event_type: OrderbookEventType::Cancelled(order.clone()), + }); + } else { + error!("Failed to append Cancelled event"); + } + Ok(()) + } + + async fn register_fulfilled( + &self, + block_id: u64, + block_timestamp: u64, + order: &FulfilledData, + ) -> StorageResult<()> { + trace!("FULFILLED {} {:?}", block_id, order); + if let Ok(mut events) = self.events.lock() { + events.push(OrderbookEvent { + block_id, + block_timestamp, + event_type: OrderbookEventType::Fulfilled(order.clone()), + }); + } else { + error!("Failed to append Fulfilled event"); + } + Ok(()) + } + + async fn register_executed( + &self, + block_id: u64, + block_timestamp: u64, + order: &ExecutedData, + ) -> StorageResult<()> { + trace!("EXECUTED {} {:?}", block_id, order); + if let Ok(mut events) = self.events.lock() { + events.push(OrderbookEvent { + block_id, + block_timestamp, + event_type: OrderbookEventType::Executed(order.clone()), + }); + } else { + error!("Failed to append Executed event"); + } + Ok(()) + } + + async fn status_back_to_open( + &self, + block_id: u64, + block_timestamp: u64, + order: &RollbackStatusData, + ) -> StorageResult<()> { + trace!("ROLLBACK {} {:?}", block_id, order); + if let Ok(mut events) = self.events.lock() { + events.push(OrderbookEvent { + block_id, + block_timestamp, + event_type: OrderbookEventType::RollbackStatus(order.clone()), + }); + } else { + error!("Failed to append Executed event"); + } + Ok(()) + } +} + +struct DefaultEventHandler; + +#[async_trait] +impl EventHandler for DefaultEventHandler { + async fn on_block_processed(&self, block_number: u64) { + info!("event: block processed {:?}", block_number); + } +} diff --git a/crates/diri/src/lib.rs b/crates/diri/src/lib.rs index 661d41420..c3d4ff509 100644 --- a/crates/diri/src/lib.rs +++ b/crates/diri/src/lib.rs @@ -4,10 +4,8 @@ use storage::*; pub mod event_handler; use event_handler::EventHandler; -mod orderbook; - use starknet::core::types::{ - BlockId, EmittedEvent, EventFilter, FieldElement, MaybePendingBlockWithTxHashes, + BlockId, EmittedEvent, EventFilter, Felt, MaybePendingBlockWithTxHashes, }; use starknet::macros::selector; use starknet::providers::{AnyProvider, Provider, ProviderError}; @@ -15,7 +13,7 @@ use std::collections::HashMap; use std::sync::Arc; use tracing::{error, trace, warn}; -use crate::orderbook::Event; +use orderbook::Event; pub type IndexerResult = Result; @@ -61,11 +59,13 @@ impl Diri { &self, from_block: BlockId, to_block: BlockId, + address: Option, ) -> IndexerResult<()> { let blocks_events = self .fetch_events( from_block, to_block, + address, Some(vec![vec![ selector!("OrderPlaced"), selector!("OrderFulfilled"), @@ -76,11 +76,15 @@ impl Diri { ) .await?; - for (block_number, events) in blocks_events { - let block_timestamp = self.block_time(BlockId::Number(block_number)).await?; + // Handle events sorted by block number + let mut block_numbers: Vec<&u64> = blocks_events.keys().collect(); + block_numbers.sort(); + for block_number in block_numbers { + let block_timestamp = self.block_time(BlockId::Number(*block_number)).await?; + let events = blocks_events.get(block_number).unwrap(); for any_event in events { - let orderbook_event: Event = match any_event.try_into() { + let orderbook_event: Event = match any_event.clone().try_into() { Ok(ev) => ev, Err(e) => { trace!("Event can't be deserialized: {e}"); @@ -92,38 +96,40 @@ impl Diri { Event::OrderPlaced(ev) => { trace!("OrderPlaced found: {:?}", ev); self.storage - .register_placed(block_number, block_timestamp, &ev.into()) + .register_placed(*block_number, block_timestamp, &ev.into()) .await?; } Event::OrderCancelled(ev) => { trace!("OrderCancelled found: {:?}", ev); self.storage - .register_cancelled(block_number, block_timestamp, &ev.into()) + .register_cancelled(*block_number, block_timestamp, &ev.into()) .await?; } Event::OrderFulfilled(ev) => { trace!("OrderFulfilled found: {:?}", ev); self.storage - .register_fulfilled(block_number, block_timestamp, &ev.into()) + .register_fulfilled(*block_number, block_timestamp, &ev.into()) .await?; } Event::OrderExecuted(ev) => { trace!("OrderExecuted found: {:?}", ev); self.storage - .register_executed(block_number, block_timestamp, &ev.into()) + .register_executed(*block_number, block_timestamp, &ev.into()) .await?; } Event::RollbackStatus(ev) => { trace!("RollbackStatus found: {:?}", ev); self.storage - .status_back_to_open(block_number, block_timestamp, &ev.into()) + .status_back_to_open(*block_number, block_timestamp, &ev.into()) .await?; } - _ => warn!("Orderbook event not handled: {:?}", orderbook_event), + _ => { + warn!("Orderbook event not handled: {:?}", orderbook_event) + } }; } - self.event_handler.on_block_processed(block_number).await; + self.event_handler.on_block_processed(*block_number).await; } Ok(()) @@ -145,7 +151,8 @@ impl Diri { &self, from_block: BlockId, to_block: BlockId, - keys: Option>>, + address: Option, + keys: Option>>, ) -> Result>, IndexerError> { // TODO: setup key filtering here. @@ -154,7 +161,7 @@ impl Diri { let filter = EventFilter { from_block: Some(from_block), to_block: Some(to_block), - address: None, + address, keys, }; @@ -169,7 +176,7 @@ impl Diri { event_page.events.iter().for_each(|e| { events - .entry(e.block_number) + .entry(e.block_number.unwrap()) .and_modify(|v| v.push(e.clone())) .or_insert(vec![e.clone()]); }); diff --git a/crates/diri/src/orderbook.rs b/crates/diri/src/orderbook.rs deleted file mode 100644 index 52d5a302f..000000000 --- a/crates/diri/src/orderbook.rs +++ /dev/null @@ -1,136 +0,0 @@ -use cainome::rs::abigen; -use starknet::{ - core::types::{EmittedEvent, FieldElement}, - macros::selector, -}; - -// TODO: check a way to fix the path... because when compiled from -// ark-services, the path is not valid as it's relative to Cargo manifest file. -abigen!( - Orderbook, - "./artifacts/orderbook.abi.json", - type_aliases { - ark_orderbook::orderbook::orderbook::Event as EventV0; - ark_orderbook::orderbook::orderbook::OrderExecuted as OrderExecutedV0; - } -); - -abigen!( - OrderBook, - r#" - [ - { - "type": "event", - "name": "ark_orderbook::orderbook::orderbook::Event", - "kind": "enum", - "variants": [ - { - "name": "OrderExecuted", - "type": "ark_orderbook::orderbook::orderbook::OrderExecuted", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "ark_orderbook::orderbook::orderbook::OrderExecuted", - "kind": "struct", - "members": [ - { - "name": "order_hash", - "type": "core::felt252", - "kind": "key" - }, - { - "name": "order_status", - "type": "ark_common::protocol::order_types::OrderStatus", - "kind": "key" - }, - { - "name": "version", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "transaction_hash", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "from", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "to", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - } - ] - "# -, type_aliases { - ark_orderbook::orderbook::orderbook::Event as EventV1; - ark_orderbook::orderbook::orderbook::OrderExecuted as OrderExecutedV1; - } -); - -#[derive(Debug)] -pub(crate) enum OrderExecuted { - V0(OrderExecutedV0), - V1(OrderExecutedV1), -} - -#[derive(Debug)] -pub(crate) enum Event { - OrderPlaced(OrderPlaced), - OrderExecuted(OrderExecuted), - OrderCancelled(OrderCancelled), - RollbackStatus(RollbackStatus), - OrderFulfilled(OrderFulfilled), - Upgraded(Upgraded), - Unknown, -} - -impl From for Event { - fn from(ev: EmittedEvent) -> Self { - if ev.keys[0] == selector!("OrderExecuted") { - if ev.data.len() > 0 { - let version = ev.data[0]; - if version == FieldElement::ONE {} - // Version 1 - TryInto::::try_into(ev).unwrap().into() - } else { - // Version 0 - TryInto::::try_into(ev).unwrap().into() - } - } else { - match TryInto::::try_into(ev) { - Ok(ev) => ev.into(), - Err(_) => Event::Unknown, - } - } - } -} - -impl From for Event { - fn from(ev: EventV0) -> Self { - match ev { - EventV0::OrderCancelled(ev) => Event::OrderCancelled(ev), - EventV0::OrderPlaced(ev) => Event::OrderPlaced(ev), - EventV0::OrderFulfilled(ev) => Event::OrderFulfilled(ev), - EventV0::RollbackStatus(ev) => Event::RollbackStatus(ev), - EventV0::Upgraded(ev) => Event::Upgraded(ev), - EventV0::OrderExecuted(ev) => Event::OrderExecuted(OrderExecuted::V0(ev)), - } - } -} - -impl From for Event { - fn from(ev: EventV1) -> Self { - match ev { - EventV1::OrderExecuted(ev) => Event::OrderExecuted(OrderExecuted::V1(ev)), - } - } -} diff --git a/crates/diri/src/storage/types.rs b/crates/diri/src/storage/types.rs index 030591954..7c5f15862 100644 --- a/crates/diri/src/storage/types.rs +++ b/crates/diri/src/storage/types.rs @@ -1,12 +1,8 @@ -use num_bigint::BigUint; - -use starknet::core::types::FieldElement; -use starknet::core::utils::parse_cairo_short_string; -use std::fmt::LowerHex; - -use crate::orderbook::{ - OrderCancelled, OrderExecuted, OrderFulfilled, OrderPlaced, RollbackStatus, U256, +use orderbook::events::{ + common::{to_hex_str, to_hex_str_opt, u256_to_hex, u256_to_hex_opt}, + OrderCancelled, OrderExecuted, OrderFulfilled, OrderPlaced, RollbackStatus, }; +use starknet::core::{types::Felt, utils::parse_cairo_short_string}; #[derive(Debug, Clone)] pub struct PlacedData { @@ -31,95 +27,58 @@ pub struct PlacedData { pub broker_id: String, } -impl From for PlacedData { - fn from(value: OrderPlaced) -> Self { - Self { - order_hash: to_hex_str(&value.order_hash), - order_version: to_hex_str(&value.order_version), - order_type: format!("{:?}", value.order_type), - cancelled_order_hash: to_hex_str_opt(&value.cancelled_order_hash), - route: format!("{:?}", value.order.route), - currency_address: to_hex_str(&FieldElement::from(value.order.currency_address)), - currency_chain_id: to_hex_str(&value.order.currency_chain_id), - salt: to_hex_str(&value.order.salt), - offerer: to_hex_str(&FieldElement::from(value.order.offerer)), - token_chain_id: format!("0x{:x}", value.order.token_chain_id), - token_address: to_hex_str(&FieldElement::from(value.order.token_address)), - token_id: u256_to_hex_opt(&value.order.token_id), - quantity: u256_to_hex(&value.order.quantity), - start_amount: u256_to_hex(&value.order.start_amount), - end_amount: u256_to_hex(&value.order.end_amount), - start_date: value.order.start_date, - end_date: value.order.end_date, - broker_id: to_hex_str(&FieldElement::from(value.order.broker_id)), - } - } -} - #[derive(Debug, Clone)] pub struct CancelledData { pub order_hash: String, + pub order_type: String, pub reason: String, } -impl From for CancelledData { - fn from(value: OrderCancelled) -> Self { - Self { - order_hash: to_hex_str(&value.order_hash), - reason: parse_cairo_short_string(&value.reason).unwrap_or(to_hex_str(&value.reason)), - } - } -} - #[derive(Debug, Clone)] pub struct RollbackStatusData { pub order_hash: String, + pub order_type: String, pub reason: String, } -impl From for RollbackStatusData { - fn from(value: RollbackStatus) -> Self { - Self { - order_hash: to_hex_str(&value.order_hash), - reason: parse_cairo_short_string(&value.reason).unwrap_or(to_hex_str(&value.reason)), - } - } -} - #[derive(Debug, Clone)] pub struct FulfilledData { pub order_hash: String, + pub order_type: String, pub fulfiller: String, pub related_order_hash: Option, } -impl From for FulfilledData { - fn from(value: OrderFulfilled) -> Self { - let related_order_hash = value.related_order_hash.map(FieldElement::from); - - Self { - order_hash: to_hex_str(&value.order_hash), - fulfiller: to_hex_str(&FieldElement::from(value.fulfiller)), - related_order_hash: to_hex_str_opt(&related_order_hash), - } - } -} - #[derive(Debug, Clone)] pub struct ExecutedData { pub version: u8, pub order_hash: String, + pub order_type: Option, pub transaction_hash: Option, pub from: Option, pub to: Option, } +impl From for CancelledData { + fn from(value: OrderCancelled) -> Self { + match value { + OrderCancelled::V1(value) => Self { + order_hash: to_hex_str(&value.order_hash), + order_type: format!("{:?}", value.order_type), + reason: parse_cairo_short_string(&value.reason) + .unwrap_or(to_hex_str(&value.reason)), + }, + } + } +} + impl From for ExecutedData { fn from(value: OrderExecuted) -> Self { match value { OrderExecuted::V0(v) => Self { version: 0, order_hash: to_hex_str(&v.order_hash), + order_type: None, transaction_hash: None, from: None, to: None, @@ -127,40 +86,76 @@ impl From for ExecutedData { OrderExecuted::V1(v) => Self { version: 1, order_hash: to_hex_str(&v.order_hash), - transaction_hash: Some(to_hex_str(&FieldElement::from(v.transaction_hash))), - from: Some(to_hex_str(&FieldElement::from(v.from))), - to: Some(to_hex_str(&FieldElement::from(v.to))), + order_type: None, + transaction_hash: Some(to_hex_str(&v.transaction_hash)), + from: Some(to_hex_str(&Felt::from(v.from))), + to: Some(to_hex_str(&Felt::from(v.to))), + }, + OrderExecuted::V2(v) => Self { + version: 2, + order_hash: to_hex_str(&v.order_hash), + order_type: Some(format!("{:?}", v.order_type)), + transaction_hash: Some(to_hex_str(&v.transaction_hash)), + from: Some(to_hex_str(&Felt::from(v.from))), + to: Some(to_hex_str(&Felt::from(v.to))), }, } } } -/// Returns the padded hex of '0x' prefixed -/// representation of the given felt. -/// TODO: can't use ark_starknet until starknet-rs conflict is resolved. -pub fn to_hex_str(value: &T) -> String { - format!("0x{:064x}", value) -} - -pub fn to_hex_str_opt(value: &Option) -> Option { - value.as_ref().map(|v| format!("0x{:064x}", v)) -} - -pub fn u256_to_biguint(v: &U256) -> BigUint { - let low_bytes = v.low.to_be_bytes(); - let high_bytes = v.high.to_be_bytes(); - - let mut bytes: Vec = Vec::new(); - bytes.extend(high_bytes); - bytes.extend(low_bytes); - - BigUint::from_bytes_be(&bytes[..]) +impl From for FulfilledData { + fn from(value: OrderFulfilled) -> Self { + match value { + OrderFulfilled::V1(value) => { + let related_order_hash = value.related_order_hash.map(Felt::from); + + Self { + order_hash: to_hex_str(&value.order_hash), + order_type: format!("{:?}", value.order_type), + fulfiller: to_hex_str(&Felt::from(value.fulfiller)), + related_order_hash: to_hex_str_opt(&related_order_hash), + } + } + } + } } -pub fn u256_to_hex(value: &U256) -> String { - to_hex_str(&u256_to_biguint(value)) +impl From for PlacedData { + fn from(value: OrderPlaced) -> Self { + match value { + OrderPlaced::V1(value) => Self { + order_hash: to_hex_str(&value.order_hash), + order_version: to_hex_str(&value.order_version), + order_type: format!("{:?}", value.order_type), + cancelled_order_hash: to_hex_str_opt(&value.cancelled_order_hash), + route: format!("{:?}", value.order.route), + currency_address: to_hex_str(&Felt::from(value.order.currency_address)), + currency_chain_id: to_hex_str(&value.order.currency_chain_id), + salt: to_hex_str(&value.order.salt), + offerer: to_hex_str(&Felt::from(value.order.offerer)), + token_chain_id: format!("0x{:x}", value.order.token_chain_id), + token_address: to_hex_str(&Felt::from(value.order.token_address)), + token_id: u256_to_hex_opt(&value.order.token_id), + quantity: u256_to_hex(&value.order.quantity), + start_amount: u256_to_hex(&value.order.start_amount), + end_amount: u256_to_hex(&value.order.end_amount), + start_date: value.order.start_date, + end_date: value.order.end_date, + broker_id: to_hex_str(&Felt::from(value.order.broker_id)), + }, + } + } } -pub fn u256_to_hex_opt(value: &Option) -> Option { - value.as_ref().map(|v| to_hex_str(&u256_to_biguint(v))) +impl From for RollbackStatusData { + fn from(value: RollbackStatus) -> Self { + match value { + RollbackStatus::V1(value) => Self { + order_hash: to_hex_str(&value.order_hash), + order_type: format!("{:?}", value.order_type), + reason: parse_cairo_short_string(&value.reason) + .unwrap_or(to_hex_str(&value.reason)), + }, + } + } } diff --git a/crates/orderbook/Cargo.toml b/crates/orderbook/Cargo.toml new file mode 100644 index 000000000..3f9b39228 --- /dev/null +++ b/crates/orderbook/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "orderbook" +version = "0.1.0" +edition = "2021" + +[lib] +path = "src/lib.rs" + +[dependencies] +cainome = { git = "https://github.com/cartridge-gg/cainome", tag = "v0.4.2", features = [ + "abigen-rs", +] } +num-bigint = "0.4.4" +starknet = "0.12.0" diff --git a/crates/orderbook/src/events/common.rs b/crates/orderbook/src/events/common.rs new file mode 100644 index 000000000..21642b1e0 --- /dev/null +++ b/crates/orderbook/src/events/common.rs @@ -0,0 +1,36 @@ +use cainome::cairo_serde::U256; +use num_bigint::BigUint; + +pub use starknet::core::utils::parse_cairo_short_string; + +use std::fmt::LowerHex; + +/// Returns the padded hex of '0x' prefixed +/// representation of the given felt. +/// TODO: can't use ark_starknet until starknet-rs conflict is resolved. +pub fn to_hex_str(value: &T) -> String { + format!("0x{:064x}", value) +} + +pub fn to_hex_str_opt(value: &Option) -> Option { + value.as_ref().map(|v| format!("0x{:064x}", v)) +} + +pub fn u256_to_biguint(v: &U256) -> BigUint { + let low_bytes = v.low.to_be_bytes(); + let high_bytes = v.high.to_be_bytes(); + + let mut bytes: Vec = Vec::new(); + bytes.extend(high_bytes); + bytes.extend(low_bytes); + + BigUint::from_bytes_be(&bytes[..]) +} + +pub fn u256_to_hex(value: &U256) -> String { + to_hex_str(&u256_to_biguint(value)) +} + +pub fn u256_to_hex_opt(value: &Option) -> Option { + value.as_ref().map(|v| to_hex_str(&u256_to_biguint(v))) +} diff --git a/crates/orderbook/src/events/mod.rs b/crates/orderbook/src/events/mod.rs new file mode 100644 index 000000000..ae604ac10 --- /dev/null +++ b/crates/orderbook/src/events/mod.rs @@ -0,0 +1,30 @@ +pub mod common; +pub(crate) mod order_cancelled; +pub(crate) mod order_executed; +pub(crate) mod order_fulfilled; +pub(crate) mod order_placed; +pub(crate) mod rollback_status; + +pub use order_cancelled::OrderCancelled; +pub use order_executed::OrderExecuted; +pub use order_fulfilled::OrderFulfilled; +pub use order_placed::OrderPlaced; +pub use rollback_status::RollbackStatus; + +// pub(crate) use cainome::cairo_serde::U256; +use starknet::{core::types::Felt, macros::selector}; + +#[derive(Debug)] +pub enum OrderbookParseError { + Selector, + KeyLength, + DataLength, + UnsupportedVersion, + UnknownError, +} + +pub const ORDER_CANCELLED_SELECTOR: Felt = selector!("OrderCancelled"); +pub const ORDER_EXECUTED_SELECTOR: Felt = selector!("OrderExecuted"); +pub const ORDER_FULFILLED_SELECTOR: Felt = selector!("OrderFulfilled"); +pub const ORDER_PLACED_SELECTOR: Felt = selector!("OrderPlaced"); +pub const ROLLBACK_STATUS_SELECTOR: Felt = selector!("RollbackStatus"); diff --git a/crates/orderbook/src/events/order_cancelled.rs b/crates/orderbook/src/events/order_cancelled.rs new file mode 100644 index 000000000..485d95df6 --- /dev/null +++ b/crates/orderbook/src/events/order_cancelled.rs @@ -0,0 +1,108 @@ +use cainome::rs::abigen; +use starknet::core::types::{EmittedEvent, Felt}; + +use super::{OrderbookParseError, ORDER_CANCELLED_SELECTOR}; + +abigen!( + V1, + r#" + [ + { + "type": "enum", + "name": "ark_common::protocol::order_types::OrderType", + "variants": [ + { + "name": "Listing", + "type": "()" + }, + { + "name": "Auction", + "type": "()" + }, + { + "name": "Offer", + "type": "()" + }, + { + "name": "CollectionOffer", + "type": "()" + } + ] + }, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "OrderCancelled", + "type": "ark_component::orderbook::orderbook::OrderbookComponent::OrderCancelled", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::OrderCancelled", + "kind": "struct", + "members": [ + { + "name": "order_hash", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "reason", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "order_type", + "type": "ark_common::protocol::order_types::OrderType", + "kind": "key" + }, + { + "name": "version", + "type": "core::integer::u8", + "kind": "data" + } + ] + } + ]"#, + type_aliases { + ark_component::orderbook::orderbook::OrderbookComponent::Event as EventV1; + ark_component::orderbook::orderbook::OrderbookComponent::OrderCancelled as OrderCancelledV1; + }, + derives(Debug), +); + +#[derive(Debug)] +pub enum OrderCancelled { + V1(OrderCancelledV1), +} + +impl TryFrom for OrderCancelled { + type Error = OrderbookParseError; + + fn try_from(ev: EmittedEvent) -> Result { + if ev.keys[0] == ORDER_CANCELLED_SELECTOR { + if !ev.data.is_empty() { + let version = ev.data[0]; + if version == Felt::ONE { + match TryInto::::try_into(ev) { + Ok(event) => match event { + EventV1::OrderCancelled(ev) => return Ok(OrderCancelled::V1(ev)), + }, + Err(_) => return Err(OrderbookParseError::UnknownError), + } + } + Err(OrderbookParseError::UnsupportedVersion) + } else { + // Old version + Err(OrderbookParseError::UnknownError) + } + } else { + Err(OrderbookParseError::Selector) + } + } +} diff --git a/crates/orderbook/src/events/order_executed.rs b/crates/orderbook/src/events/order_executed.rs new file mode 100644 index 000000000..7e341b19b --- /dev/null +++ b/crates/orderbook/src/events/order_executed.rs @@ -0,0 +1,371 @@ +use cainome::rs::abigen; +use starknet::core::types::{EmittedEvent, Felt}; + +use super::{OrderbookParseError, ORDER_EXECUTED_SELECTOR}; + +abigen!( + V0, + r#" + [ + { + "type": "enum", + "name": "ark_common::protocol::order_types::OrderStatus", + "variants": [ + { + "name": "Open", + "type": "()" + }, + { + "name": "Fulfilled", + "type": "()" + }, + { + "name": "Executed", + "type": "()" + }, + { + "name": "CancelledUser", + "type": "()" + }, + { + "name": "CancelledByNewOrder", + "type": "()" + }, + { + "name": "CancelledAssetFault", + "type": "()" + }, + { + "name": "CancelledOwnership", + "type": "()" + } + ] + }, + { + "type": "event", + "name": "ark_orderbook::orderbook::orderbook::Event", + "kind": "enum", + "variants": [ + { + "name": "OrderExecuted", + "type": "ark_orderbook::orderbook::orderbook::OrderExecuted", + "kind": "nested" + } + ] +}, + { + "type": "event", + "name": "ark_orderbook::orderbook::orderbook::OrderExecuted", + "kind": "struct", + "members": [ + { + "name": "order_hash", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "order_status", + "type": "ark_common::protocol::order_types::OrderStatus", + "kind": "key" + } + ] + } + ] + "# + , type_aliases { + ark_common::protocol::order_types::OrderStatus as OrderStatusV0; + ark_orderbook::orderbook::orderbook::Event as EventV0; + ark_orderbook::orderbook::orderbook::OrderExecuted as OrderExecutedV0; + }, + derives(Debug) +); + +abigen!( + V1, + r#" + [ + { + "type": "enum", + "name": "ark_common::protocol::order_types::OrderStatus", + "variants": [ + { + "name": "Open", + "type": "()" + }, + { + "name": "Fulfilled", + "type": "()" + }, + { + "name": "Executed", + "type": "()" + }, + { + "name": "CancelledUser", + "type": "()" + }, + { + "name": "CancelledByNewOrder", + "type": "()" + }, + { + "name": "CancelledAssetFault", + "type": "()" + }, + { + "name": "CancelledOwnership", + "type": "()" + } + ] +}, + { + "type": "enum", + "name": "ark_common::protocol::order_types::OrderType", + "variants": [ + { + "name": "Listing", + "type": "()" + }, + { + "name": "Auction", + "type": "()" + }, + { + "name": "Offer", + "type": "()" + }, + { + "name": "CollectionOffer", + "type": "()" + } + ] +}, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "OrderExecuted", + "type": "ark_component::orderbook::orderbook::OrderbookComponent::OrderExecuted", + "kind": "nested" + } + ] +}, +{ + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::OrderExecuted", + "kind": "struct", + "members": [ + { + "name": "order_hash", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "order_status", + "type": "ark_common::protocol::order_types::OrderStatus", + "kind": "key" + }, + { + "name": "version", + "type": "core::integer::u8", + "kind": "data" + }, + { + "name": "transaction_hash", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "from", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] +} +] +"# +, type_aliases { + ark_common::protocol::order_types::OrderStatus as OrderStatusV1; + ark_component::orderbook::orderbook::OrderbookComponent::Event as EventV1; + ark_component::orderbook::orderbook::OrderbookComponent::OrderExecuted as OrderExecutedV1; +}, +derives(Debug) +); + +abigen!( + V2, + r#" + [ + { + "type": "enum", + "name": "ark_common::protocol::order_types::OrderStatus", + "variants": [ + { + "name": "Open", + "type": "()" + }, + { + "name": "Fulfilled", + "type": "()" + }, + { + "name": "Executed", + "type": "()" + }, + { + "name": "CancelledUser", + "type": "()" + }, + { + "name": "CancelledByNewOrder", + "type": "()" + }, + { + "name": "CancelledAssetFault", + "type": "()" + }, + { + "name": "CancelledOwnership", + "type": "()" + } + ] + }, + { + "type": "enum", + "name": "ark_common::protocol::order_types::OrderType", + "variants": [ + { + "name": "Listing", + "type": "()" + }, + { + "name": "Auction", + "type": "()" + }, + { + "name": "Offer", + "type": "()" + }, + { + "name": "CollectionOffer", + "type": "()" + } + ] + }, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "OrderExecuted", + "type": "ark_component::orderbook::orderbook::OrderbookComponent::OrderExecuted", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::OrderExecuted", + "kind": "struct", + "members": [ + { + "name": "order_hash", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "order_status", + "type": "ark_common::protocol::order_types::OrderStatus", + "kind": "key" + }, + { + "name": "order_type", + "type": "ark_common::protocol::order_types::OrderType", + "kind": "key" + }, + { + "name": "version", + "type": "core::integer::u8", + "kind": "data" + }, + { + "name": "transaction_hash", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "from", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + } + ] + "# +, type_aliases { + ark_common::protocol::order_types::OrderStatus as OrderStatusV2; + ark_common::protocol::order_types::OrderType as OrderTypeV2; + ark_component::orderbook::orderbook::OrderbookComponent::Event as EventV2; + ark_component::orderbook::orderbook::OrderbookComponent::OrderExecuted as OrderExecutedV2; + }, + derives(Debug) +); + +#[derive(Debug)] +pub enum OrderExecuted { + V0(OrderExecutedV0), + V1(OrderExecutedV1), + V2(OrderExecutedV2), +} + +impl TryFrom for OrderExecuted { + type Error = OrderbookParseError; + + fn try_from(ev: EmittedEvent) -> Result { + if ev.keys[0] == ORDER_EXECUTED_SELECTOR { + if !ev.data.is_empty() { + let version = ev.data[0]; + if version == Felt::ONE { + match TryInto::::try_into(ev) { + Ok(event) => match event { + EventV1::OrderExecuted(ev) => Ok(OrderExecuted::V1(ev)), + }, + Err(_) => Err(OrderbookParseError::UnknownError), + } + } else if version == Felt::TWO { + match TryInto::::try_into(ev) { + Ok(event) => match event { + EventV2::OrderExecuted(ev) => Ok(OrderExecuted::V2(ev)), + }, + Err(_) => Err(OrderbookParseError::UnknownError), + } + } else { + Err(OrderbookParseError::UnsupportedVersion) + } + } else { + // version 0 + match TryInto::::try_into(ev) { + Ok(event) => match event { + EventV0::OrderExecuted(ev) => Ok(OrderExecuted::V0(ev)), + }, + Err(_) => Err(OrderbookParseError::UnknownError), + } + } + } else { + Err(OrderbookParseError::Selector) + } + } +} diff --git a/crates/orderbook/src/events/order_fulfilled.rs b/crates/orderbook/src/events/order_fulfilled.rs new file mode 100644 index 000000000..86a2b81f8 --- /dev/null +++ b/crates/orderbook/src/events/order_fulfilled.rs @@ -0,0 +1,113 @@ +use cainome::rs::abigen; +use starknet::core::types::{EmittedEvent, Felt}; + +use super::{OrderbookParseError, ORDER_FULFILLED_SELECTOR}; + +abigen!( + V1, + r#" + [ + { + "type": "enum", + "name": "ark_common::protocol::order_types::OrderType", + "variants": [ + { + "name": "Listing", + "type": "()" + }, + { + "name": "Auction", + "type": "()" + }, + { + "name": "Offer", + "type": "()" + }, + { + "name": "CollectionOffer", + "type": "()" + } + ] + }, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "OrderFulfilled", + "type": "ark_component::orderbook::orderbook::OrderbookComponent::OrderFulfilled", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::OrderFulfilled", + "kind": "struct", + "members": [ + { + "name": "order_hash", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "fulfiller", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "related_order_hash", + "type": "core::option::Option::", + "kind": "key" + }, + { + "name": "order_type", + "type": "ark_common::protocol::order_types::OrderType", + "kind": "key" + }, + { + "name": "version", + "type": "core::integer::u8", + "kind": "data" + } + ] + } + ] + "#, + type_aliases { + ark_component::orderbook::orderbook::OrderbookComponent::Event as EventV1; + ark_component::orderbook::orderbook::OrderbookComponent::OrderFulfilled as OrderFulfilledV1; + }, + derives(Debug), +); + +#[derive(Debug)] +pub enum OrderFulfilled { + V1(OrderFulfilledV1), +} + +impl TryFrom for OrderFulfilled { + type Error = OrderbookParseError; + + fn try_from(ev: EmittedEvent) -> Result { + if ev.keys[0] == ORDER_FULFILLED_SELECTOR { + if !ev.data.is_empty() { + let version = ev.data[0]; + if version == Felt::ONE { + match TryInto::::try_into(ev) { + Ok(event) => match event { + EventV1::OrderFulfilled(ev) => return Ok(OrderFulfilled::V1(ev)), + }, + Err(_) => return Err(OrderbookParseError::UnknownError), + }; + } + Err(OrderbookParseError::UnsupportedVersion) + } else { + Err(OrderbookParseError::UnknownError) + } + } else { + Err(OrderbookParseError::Selector) + } + } +} diff --git a/crates/orderbook/src/events/order_placed.rs b/crates/orderbook/src/events/order_placed.rs new file mode 100644 index 000000000..c6c022dce --- /dev/null +++ b/crates/orderbook/src/events/order_placed.rs @@ -0,0 +1,230 @@ +use cainome::rs::abigen; +use starknet::core::types::{EmittedEvent, Felt}; + +use super::{OrderbookParseError, ORDER_PLACED_SELECTOR}; + +abigen!( + V1, + r#" + [ + { + "type": "enum", + "name": "ark_common::protocol::order_types::OrderType", + "variants": [ + { + "name": "Listing", + "type": "()" + }, + { + "name": "Auction", + "type": "()" + }, + { + "name": "Offer", + "type": "()" + }, + { + "name": "CollectionOffer", + "type": "()" + } + ] + }, + { + "type": "enum", + "name": "ark_common::protocol::order_types::RouteType", + "variants": [ + { + "name": "Erc20ToErc721", + "type": "()" + }, + { + "name": "Erc721ToErc20", + "type": "()" + }, + { + "name": "Erc20ToErc1155", + "type": "()" + }, + { + "name": "Erc1155ToErc20", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "ark_common::protocol::order_v1::OrderV1", + "members": [ + { + "name": "route", + "type": "ark_common::protocol::order_types::RouteType" + }, + { + "name": "currency_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "currency_chain_id", + "type": "core::felt252" + }, + { + "name": "salt", + "type": "core::felt252" + }, + { + "name": "offerer", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "token_chain_id", + "type": "core::felt252" + }, + { + "name": "token_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "token_id", + "type": "core::option::Option::" + }, + { + "name": "quantity", + "type": "core::integer::u256" + }, + { + "name": "start_amount", + "type": "core::integer::u256" + }, + { + "name": "end_amount", + "type": "core::integer::u256" + }, + { + "name": "start_date", + "type": "core::integer::u64" + }, + { + "name": "end_date", + "type": "core::integer::u64" + }, + { + "name": "broker_id", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "additional_data", + "type": "core::array::Span::" + } + ] + }, + + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "OrderPlaced", + "type": "ark_component::orderbook::orderbook::OrderbookComponent::OrderPlaced", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::OrderPlaced", + "kind": "struct", + "members": [ + { + "name": "order_hash", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "order_version", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "order_type", + "type": "ark_common::protocol::order_types::OrderType", + "kind": "key" + }, + { + "name": "version", + "type": "core::integer::u8", + "kind": "data" + }, + { + "name": "cancelled_order_hash", + "type": "core::option::Option::", + "kind": "data" + }, + { + "name": "order", + "type": "ark_common::protocol::order_v1::OrderV1", + "kind": "data" + } + ] + } + ] + "#, + type_aliases { + ark_component::orderbook::orderbook::OrderbookComponent::Event as EventV1; + ark_component::orderbook::orderbook::OrderbookComponent::OrderPlaced as OrderPlacedV1; + }, + derives(Debug), +); + +#[derive(Debug)] +pub enum OrderPlaced { + V1(OrderPlacedV1), +} + +impl TryFrom for OrderPlaced { + type Error = OrderbookParseError; + + fn try_from(ev: EmittedEvent) -> Result { + if ev.keys[0] == ORDER_PLACED_SELECTOR { + if ev.data.len() > 2 { + let version = ev.data[0]; + if version == Felt::ONE { + match TryInto::::try_into(ev) { + Ok(event) => match event { + EventV1::OrderPlaced(ev) => return Ok(OrderPlaced::V1(ev)), + }, + Err(_) => return Err(OrderbookParseError::UnknownError), + } + } + Err(OrderbookParseError::UnsupportedVersion) + } else { + // Old version + Err(OrderbookParseError::UnknownError) + } + } else { + Err(OrderbookParseError::Selector) + } + } +} + +impl From<&RouteType> for crate::RouteType { + fn from(value: &RouteType) -> Self { + match value { + RouteType::Erc20ToErc721 => crate::RouteType::Erc20ToErc721, + RouteType::Erc721ToErc20 => crate::RouteType::Erc721ToErc20, + RouteType::Erc20ToErc1155 => crate::RouteType::Erc20ToErc1155, + RouteType::Erc1155ToErc20 => crate::RouteType::Erc1155ToErc20, + } + } +} + +impl From<&OrderType> for crate::OrderType { + fn from(value: &OrderType) -> Self { + match value { + OrderType::Listing => crate::OrderType::Listing, + OrderType::Auction => crate::OrderType::Auction, + OrderType::Offer => crate::OrderType::Offer, + OrderType::CollectionOffer => crate::OrderType::CollectionOffer, + } + } +} diff --git a/crates/orderbook/src/events/rollback_status.rs b/crates/orderbook/src/events/rollback_status.rs new file mode 100644 index 000000000..646a01001 --- /dev/null +++ b/crates/orderbook/src/events/rollback_status.rs @@ -0,0 +1,109 @@ +use cainome::rs::abigen; +use starknet::core::types::{EmittedEvent, Felt}; + +use super::{OrderbookParseError, ROLLBACK_STATUS_SELECTOR}; + +abigen!( + V1, + r#" + [ + { + "type": "enum", + "name": "ark_common::protocol::order_types::OrderType", + "variants": [ + { + "name": "Listing", + "type": "()" + }, + { + "name": "Auction", + "type": "()" + }, + { + "name": "Offer", + "type": "()" + }, + { + "name": "CollectionOffer", + "type": "()" + } + ] + }, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "RollbackStatus", + "type": "ark_component::orderbook::orderbook::OrderbookComponent::RollbackStatus", + "kind": "nested" + } + ] +}, + { + "type": "event", + "name": "ark_component::orderbook::orderbook::OrderbookComponent::RollbackStatus", + "kind": "struct", + "members": [ + { + "name": "order_hash", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "reason", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "order_type", + "type": "ark_common::protocol::order_types::OrderType", + "kind": "key" + }, + { + "name": "version", + "type": "core::integer::u8", + "kind": "data" + } + ] +} + ] + "#, + type_aliases { + ark_component::orderbook::orderbook::OrderbookComponent::Event as EventV1; + ark_component::orderbook::orderbook::OrderbookComponent::RollbackStatus as RollbackStatusV1; + }, + derives(Debug), +); + +#[derive(Debug)] +pub enum RollbackStatus { + V1(RollbackStatusV1), +} + +impl TryFrom for RollbackStatus { + type Error = OrderbookParseError; + + fn try_from(ev: EmittedEvent) -> Result { + if ev.keys[0] == ROLLBACK_STATUS_SELECTOR { + if ev.data.len() > 2 { + let version = ev.data[0]; + if version == Felt::ONE { + match TryInto::::try_into(ev) { + Ok(event) => match event { + EventV1::RollbackStatus(ev) => return Ok(RollbackStatus::V1(ev)), + }, + Err(_) => return Err(OrderbookParseError::UnknownError), + } + } + Err(OrderbookParseError::UnsupportedVersion) + } else { + // Old version + Err(OrderbookParseError::UnknownError) + } + } else { + Err(OrderbookParseError::Selector) + } + } +} diff --git a/crates/orderbook/src/lib.rs b/crates/orderbook/src/lib.rs new file mode 100644 index 000000000..3f9667b24 --- /dev/null +++ b/crates/orderbook/src/lib.rs @@ -0,0 +1,71 @@ +use events::{ + OrderCancelled, OrderExecuted, OrderFulfilled, OrderPlaced, RollbackStatus, + ORDER_CANCELLED_SELECTOR, ORDER_EXECUTED_SELECTOR, ORDER_FULFILLED_SELECTOR, + ORDER_PLACED_SELECTOR, +}; +use starknet::core::types::EmittedEvent; + +pub mod events; + +#[derive(Debug)] +pub enum Event { + OrderPlaced(OrderPlaced), + OrderExecuted(OrderExecuted), + OrderCancelled(OrderCancelled), + RollbackStatus(RollbackStatus), + OrderFulfilled(OrderFulfilled), + Unknown, +} + +impl From for Event { + fn from(ev: EmittedEvent) -> Self { + match ev.keys[0] { + key if key == ORDER_CANCELLED_SELECTOR => match TryInto::::try_into(ev) + { + Ok(ev) => Event::OrderCancelled(ev), + Err(_) => Event::Unknown, + }, + key if key == ORDER_EXECUTED_SELECTOR => match TryInto::::try_into(ev) { + Ok(ev) => Event::OrderExecuted(ev), + Err(_) => Event::Unknown, + }, + + key if key == ORDER_FULFILLED_SELECTOR => match TryInto::::try_into(ev) + { + Ok(ev) => Event::OrderFulfilled(ev), + Err(_) => Event::Unknown, + }, + key if key == ORDER_PLACED_SELECTOR => match TryInto::::try_into(ev) { + Ok(ev) => Event::OrderPlaced(ev), + Err(_) => Event::Unknown, + }, + _ => Event::Unknown, + } + } +} + +pub enum RouteType { + Erc20ToErc721, + Erc721ToErc20, + Erc20ToErc1155, + Erc1155ToErc20, +} + +pub enum OrderType { + Listing, + Auction, + Offer, + CollectionOffer, +} + +pub mod error { + use starknet::core::types::Felt; + + pub const CANCELLED_USER: Felt = Felt::from_hex_unchecked("0x43414e43454c4c45445f55534552"); + pub const CANCELLED_BY_NEW_ORDER: Felt = + Felt::from_hex_unchecked("0x43414e43454c4c45445f4e45575f4f52444552"); + pub const CANCELLED_ASSET_FAULT: Felt = + Felt::from_hex_unchecked("0x43414e43454c4c45445f41535345545f4641554c54"); + pub const CANCELLED_OWNERSHIP: Felt = + Felt::from_hex_unchecked("0x43414e43454c4c45445f4f574e455253484950"); +} diff --git a/crates/pontos/Cargo.toml b/crates/pontos/Cargo.toml index d6671c8e6..8a1b4ff75 100644 --- a/crates/pontos/Cargo.toml +++ b/crates/pontos/Cargo.toml @@ -13,7 +13,7 @@ serde_json = "1.0" thiserror = "1.0.32" version-compare = "0.2.0" tracing = "0.1" -sqlx = { version = "0.7", optional = true } +sqlx = { version = "0.8.2", optional = true } anyhow.workspace = true tokio.workspace = true ark-starknet.workspace = true diff --git a/crates/sana/Cargo.toml b/crates/sana/Cargo.toml index 128cdec44..990d8b679 100644 --- a/crates/sana/Cargo.toml +++ b/crates/sana/Cargo.toml @@ -13,7 +13,7 @@ serde_json = "1.0" thiserror = "1.0.32" version-compare = "0.2.0" tracing = "0.1" -sqlx = { version = "0.7", optional = true, features = [ +sqlx = { version = "0.8.2", optional = true, features = [ "postgres", "runtime-tokio", "json", diff --git a/crates/solis-legacy/.gitignore b/crates/solis-legacy/.gitignore deleted file mode 100644 index 4f2634eb8..000000000 --- a/crates/solis-legacy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -messaging.goerli.json -messaging.json diff --git a/crates/solis-legacy/Cargo.toml b/crates/solis-legacy/Cargo.toml deleted file mode 100644 index 6c1ffa2f2..000000000 --- a/crates/solis-legacy/Cargo.toml +++ /dev/null @@ -1,113 +0,0 @@ - -[package] -name = "solis" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.75" -assert_matches = "1.5.0" -async-trait = "0.1.68" -base64 = "0.21.2" -blockifier = { git = "https://github.com/starkware-libs/blockifier", tag = "v0.4.0-rc9.2" } -cairo-lang-casm = "=2.4.0" -cairo-lang-compiler = "=2.4.0" -cairo-lang-debug = "=2.4.0" -cairo-lang-defs = "=2.4.0" -cairo-lang-diagnostics = "=2.4.0" -cairo-lang-filesystem = "=2.4.0" -cairo-lang-formatter = "=2.4.0" -cairo-lang-language-server = "=2.4.0" -cairo-lang-lowering = "=2.4.0" -cairo-lang-parser = "=2.4.0" -cairo-lang-plugins = "=2.4.0" -cairo-lang-project = "=2.4.0" -cairo-lang-semantic = { version = "=2.4.0", features = ["testing"] } -cairo-lang-sierra = "=2.4.0" -cairo-lang-sierra-generator = "=2.4.0" -cairo-lang-sierra-to-casm = "=2.4.0" -cairo-lang-starknet = "=2.4.0" -cairo-lang-syntax = "=2.4.0" -cairo-lang-test-plugin = "=2.4.0" -cairo-lang-test-runner = "=2.4.0" -cairo-lang-test-utils = "=2.4.0" -cairo-lang-utils = "=2.4.0" -cairo-vm = "0.8.2" -camino = { version = "1.1.2", features = ["serde1"] } -chrono = { version = "0.4.24", features = ["serde"] } -clap = { version = "4.2", features = ["derive"] } -clap_complete = "4.3" -colored = "2" -console = "0.15.7" -convert_case = "0.6.0" -crypto-bigint = { version = "0.5.3", features = ["serde"] } -derive_more = "0.99.17" -dotenv = "0.15.0" -env_logger = "0.10.0" -flate2 = "1.0.24" -futures = "0.3.28" -hex = "0.4.3" -indoc = "1.0.7" -itertools = "0.10.3" -lazy_static = "1.4.0" -metrics-process = "1.0.9" -num-bigint = "0.4" -once_cell = "1.0" -parking_lot = "0.12.1" -pretty_assertions = "1.2.1" -rayon = "1.8.0" -salsa = "0.16.1" -scarb = { git = "https://github.com/ArkProjectNFTs/scarb.git", tag = "v2.4.0-fix-version" } -scarb-ui = { git = "https://github.com/ArkProjectNFTs/scarb.git", tag = "v2.4.0-fix-version" } -semver = "1.0.5" -serde = { version = "1.0.192", features = ["derive"] } -serde_json = "1.0" -serde_with = "2.3.1" -smol_str = { version = "0.2.0", features = ["serde"] } -sqlx = { version = "0.7.2", features = [ - "chrono", - "macros", - "regexp", - "runtime-async-std", - "runtime-tokio", - "sqlite", - "uuid", -] } -starknet = "0.8.0" -starknet-crypto = "0.6.1" -starknet_api = "0.6.0-rc3" -strum = "0.25" -strum_macros = "0.25" -test-log = "0.2.11" -thiserror = "1.0.32" -tokio = { version = "1.32.0", features = ["full"] } -toml = "0.7.4" -tracing = "0.1.34" -tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] } -url = "2.4.0" - -# server -hyper = "0.14.27" -warp = "0.3" - -# katana-core = { path = "../../../dojo/crates/katana/core", features = [ -# "messaging", -# "starknet-messaging", -# ] } -# katana-rpc = { path = "../../../dojo/crates/katana/rpc/rpc" } -# katana-rpc-api = { path = "../../../dojo/crates/katana/rpc/rpc-api" } -# katana-primitives = { path = "../../../dojo/crates/katana/primitives" } - -katana-core = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.2.3-solis", features = [ - "messaging", - "starknet-messaging", -] } -katana-rpc = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.2.3-solis" } -katana-rpc-api = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.2.3-solis" } -katana-primitives = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.2.3-solis" } - -cainome = { git = "https://github.com/cartridge-gg/cainome", tag = "v0.2.4-fix-ord", features = [ - "abigen-rs", -] } diff --git a/crates/solis-legacy/README.md b/crates/solis-legacy/README.md deleted file mode 100644 index 364cff153..000000000 --- a/crates/solis-legacy/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Solis - -## Introduction - -Solis, the ArkChain's sequencer. - -Solis is a modified version of `Katana` from [Dojo](https://github.com/dojoengine/dojo). -For now, Solis uses a modified version of Katana from the [ArkProject fork](https://github.com/ArkProjectNFTs/dojo). But some features implemented here may be integrated into Katana itself. - -## Architecture - -Katana contains two crates: `core` and `rpc`. - -The `core` crate is responsible to handle all the sequencer logic and executes transactions using the [blockifier](https://github.com/starkware-libs/blockifier). The core was modified to add a `KatanaHooker`, which enables Solis to execute some code during the transaction lifecycle into the `core` crate of Katana. This was done to avoid modifying too much katana to add Solis customization. - -The `rpc` crate receives JSON RPC requests (+ some custom endpoints). This crate must be modified in order to remove all testing features from Katana and ensure that Solis is safe to run. Some custom endpoints for Solis may therefore be added to facilitate interactions with the chain. - -Finally, this crate contains all the processing that Solis must do in order to validate an order. The `KatanaHooker` is used at this effect, and implemented to verify that the orders contains valid assets and owners. - -There is a `args.rs` and `solis_args.rs` files. Those are related to `clap` arguments. For now the arguments are very similar to Katana, but they must be personalized for Solis. - -## How to run Solis - -To run, Solis requires some important information: - -1. A messaging configuration to interact with Starknet. You can choose between `messaging.json` and `messaging.local.json`. Those files contain all the configuration required by Katana to send/receive messages to/from a Starknet sequencer. This Starknet sequencer only required the `appchain_messaging` contract to be deployed. No other modifications. - As this configuration also contains the RPC URL of the Starknet node, Solis will then be able to call some functions on the node to verify the orders content. - -2. The orderbook address: in fact, Solis must interact with the orderbook with `l1_hander` functions. This may happen when a transaction comes in, or when a message is about to be sent to Starknet. To create the `L1HandlerTransaction`, Solis required the Orderbook's address. - -3. An admin account: the ArkChain orderbook contract is only modifiable by the ArkProject maintainer. This means that an account must be deployed to deploy and take ownership of the orderbook contract. No pre-funded account can be used for that, so you have to deploy an account (using Starkli for instance) to then use this account to operate on Solis. - -```bash -cargo run -p solis -- \ - --messaging crates/solis/messaging.local.json \ - --orderbook-address 0x1234 -``` - -As you can see, the orderbook address must be known before Solis starts. To ensure that, you have to deploy the orderbook with a known `salt`. - -## Solis default - -- port: default port is `7777`, to refer to the Everai collection with 7777 Everais. So, in order to run a Starknet node with Katana, you can keep using the default port `5050` (be sure this Katana node is up and running before starting Solis). - -- fees: by default, fees are currently disabled on Solis. - -- pre-funded accounts: dev accounts are for now limited to 2, and the seed used is the same as Katana (to ease the re-use of Starkli built-in accounts like `katana-0` and `katana-1`). - -## Work locally with Katana as Starknet node - -1. First, opens a terminal and start Katana: - -```bash -dojoup -v nightly -katana -``` - -(be aware if you have a previous version of Katana installed, you may have to remove the `~/.katana` folder) - -2. Start Solis with `messaging.local.json`, already configured with the deployed `appchain_messaging` address: - -```bash -cargo run -p solis -- \ - --messaging crates/solis/messaging.local.json \ - --orderbook-address 0x024df499c7b1b14c0e52ea237e26a7401ef70507cf72eaef105316dfb5a207a7 \ - --executor-address 0x1234 -``` - -3. Deploy the `contracts` contract on Katana: - -```bash -cd scripts/deployer -node index.js -``` - - diff --git a/crates/solis-legacy/messaging.local.json b/crates/solis-legacy/messaging.local.json deleted file mode 100644 index 2a2e69719..000000000 --- a/crates/solis-legacy/messaging.local.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "chain": "starknet", - "rpc_url": "http://0.0.0.0:5050", - "contract_address": "0x5312308bef9ca39c863c9bac8819a31f6a15ff46f4151b210141e6764ae322d", - "sender_address": "0x2d71e9c974539bb3ffb4b115e66a23d0f62a641ea66c4016e903454c8753bbc", - "private_key": "0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b", - "interval": 2, - "from_block": 0 -} \ No newline at end of file diff --git a/crates/solis-legacy/src/args.rs b/crates/solis-legacy/src/args.rs deleted file mode 100644 index 646a3308d..000000000 --- a/crates/solis-legacy/src/args.rs +++ /dev/null @@ -1,251 +0,0 @@ -//! Katana binary executable. -//! -//! ## Feature Flags -//! -//! - `jemalloc`: Uses [jemallocator](https://github.com/tikv/jemallocator) as the global allocator. -//! This is **not recommended on Windows**. See [here](https://rust-lang.github.io/rfcs/1974-global-allocators.html#jemalloc) -//! for more info. -//! - `jemalloc-prof`: Enables [jemallocator's](https://github.com/tikv/jemallocator) heap profiling -//! and leak detection functionality. See [jemalloc's opt.prof](https://jemalloc.net/jemalloc.3.html#opt.prof) -//! documentation for usage details. This is **not recommended on Windows**. See [here](https://rust-lang.github.io/rfcs/1974-global-allocators.html#jemalloc) -//! for more info. -use std::path::PathBuf; - -use clap::{Args, Parser, Subcommand}; -use clap_complete::Shell; -use katana_core::backend::config::{Environment, StarknetConfig}; -use katana_core::constants::{ - DEFAULT_GAS_PRICE, DEFAULT_INVOKE_MAX_STEPS, DEFAULT_VALIDATE_MAX_STEPS, -}; -use katana_core::sequencer::SequencerConfig; -use katana_primitives::chain::ChainId; -use katana_rpc::config::ServerConfig; -use katana_rpc_api::ApiKind; -use std::env; -use tracing::Subscriber; -use tracing_subscriber::{fmt, EnvFilter}; -use url::Url; - -use crate::CHAIN_ID_SOLIS; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -#[command(propagate_version = true)] -pub struct KatanaArgs { - #[arg(long)] - #[arg(help = "Don't print anything on startup.")] - pub silent: bool, - - #[arg(long)] - #[arg(conflicts_with = "block_time")] - #[arg(help = "Disable auto and interval mining, and mine on demand instead via an endpoint.")] - pub no_mining: bool, - - #[arg(short, long)] - #[arg(value_name = "MILLISECONDS")] - #[arg(help = "Block time in milliseconds for interval mining.")] - pub block_time: Option, - - #[arg(long)] - #[arg(value_name = "PATH")] - #[arg(help = "Directory path of the database to initialize from.")] - #[arg( - long_help = "Directory path of the database to initialize from. The path must either \ - be an empty directory or a directory which already contains a previously \ - initialized Katana database." - )] - pub db_dir: Option, - - #[arg(long)] - #[arg(value_name = "URL")] - #[arg(help = "The Starknet RPC provider to fork the network from.")] - pub rpc_url: Option, - - #[arg(long)] - pub dev: bool, - - #[arg(long)] - #[arg(help = "Output logs in JSON format.")] - pub json_log: bool, - - #[arg(long)] - #[arg(requires = "rpc_url")] - #[arg(value_name = "BLOCK_NUMBER")] - #[arg(help = "Fork the network at a specific block.")] - pub fork_block_number: Option, - - #[arg(long)] - #[arg(value_name = "PATH")] - #[arg(value_parser = katana_core::service::messaging::MessagingConfig::parse)] - #[arg(help = "Configure the messaging with an other chain.")] - #[arg( - long_help = "Configure the messaging to allow Katana listening/sending messages on a \ - settlement chain that can be Ethereum or an other Starknet sequencer. \ - The configuration file details and examples can be found here: https://book.dojoengine.org/toolchain/katana/reference.html#messaging" - )] - pub messaging: katana_core::service::messaging::MessagingConfig, - - #[command(flatten)] - #[command(next_help_heading = "Server options")] - pub server: ServerOptions, - - #[command(flatten)] - #[command(next_help_heading = "Starknet options")] - pub starknet: StarknetOptions, - - #[command(subcommand)] - pub command: Option, -} - -#[derive(Debug, Subcommand)] -pub enum Commands { - #[command(about = "Generate shell completion file for specified shell")] - Completions { shell: Shell }, -} - -#[derive(Debug, Args, Clone)] -pub struct ServerOptions { - #[arg(short, long)] - #[arg(default_value = "7777")] - #[arg(help = "Port number to listen on.")] - pub port: u16, - - #[arg(long)] - #[arg(help = "The IP address the server will listen on.")] - pub host: Option, - - #[arg(long)] - #[arg(default_value = "100")] - #[arg(help = "Maximum number of concurrent connections allowed.")] - pub max_connections: u32, -} - -#[derive(Debug, Args, Clone)] -pub struct StarknetOptions { - #[arg(long)] - #[arg(default_value = "0")] - #[arg(help = "Specify the seed for randomness of accounts to be predeployed.")] - pub seed: String, - - #[arg(long = "accounts")] - #[arg(value_name = "NUM")] - #[arg(default_value = "10")] - #[arg(help = "Number of pre-funded accounts to generate.")] - pub total_accounts: u8, - - #[arg(long)] - #[arg(help = "Disable validation when executing transactions.")] - pub disable_validate: bool, - - #[command(flatten)] - #[command(next_help_heading = "Environment options")] - pub environment: EnvironmentOptions, -} - -#[derive(Debug, Args, Clone)] -pub struct EnvironmentOptions { - #[arg(long)] - #[arg(help = "The gas price.")] - pub gas_price: Option, - - #[arg(long)] - #[arg(help = "The maximum number of steps available for the account validation logic.")] - pub validate_max_steps: Option, - - #[arg(long)] - #[arg(help = "The maximum number of steps available for the account execution logic.")] - pub invoke_max_steps: Option, -} - -impl KatanaArgs { - pub fn init_logging(&self) -> Result<(), Box> { - const DEFAULT_LOG_FILTER: &str = "info,executor=trace,forked_backend=trace,server=debug,\ - katana_core=trace,blockifier=off,jsonrpsee_server=off,\ - hyper=off,messaging=debug"; - - let builder = fmt::Subscriber::builder().with_env_filter( - EnvFilter::try_from_default_env().or(EnvFilter::try_new(DEFAULT_LOG_FILTER))?, - ); - - let subscriber: Box = if self.json_log { - Box::new(builder.json().finish()) - } else { - Box::new(builder.finish()) - }; - - Ok(tracing::subscriber::set_global_default(subscriber)?) - } - - pub fn sequencer_config(&self) -> SequencerConfig { - SequencerConfig { - block_time: self.block_time, - no_mining: self.no_mining, - messaging: Some(self.messaging.clone()), - } - } - - pub fn server_config(&self) -> ServerConfig { - let mut apis = vec![ApiKind::Starknet]; - // only enable `katana` API in dev mode - if self.dev { - apis.push(ApiKind::Katana); - } - - let rpc_user = env::var("RPC_USER").unwrap_or_else(|_| "userDefault".to_string()); - let rpc_password = - env::var("RPC_PASSWORD").unwrap_or_else(|_| "passwordDefault".to_string()); - - ServerConfig { - apis, - port: self.server.port, - host: self.server.host.clone().unwrap_or("0.0.0.0".into()), - max_connections: self.server.max_connections, - rpc_user, - rpc_password, - } - } - - pub fn starknet_config(&self) -> StarknetConfig { - StarknetConfig { - total_accounts: self.starknet.total_accounts, - seed: parse_seed(&self.starknet.seed), - disable_fee: true, - disable_validate: self.starknet.disable_validate, - fork_rpc_url: None, - fork_block_number: None, - env: Environment { - chain_id: ChainId::Id(CHAIN_ID_SOLIS), - gas_price: self - .starknet - .environment - .gas_price - .unwrap_or(DEFAULT_GAS_PRICE), - invoke_max_steps: self - .starknet - .environment - .invoke_max_steps - .unwrap_or(DEFAULT_INVOKE_MAX_STEPS), - validate_max_steps: self - .starknet - .environment - .validate_max_steps - .unwrap_or(DEFAULT_VALIDATE_MAX_STEPS), - }, - db_dir: self.db_dir.clone(), - } - } -} - -fn parse_seed(seed: &str) -> [u8; 32] { - let seed = seed.as_bytes(); - - if seed.len() >= 32 { - unsafe { *(seed[..32].as_ptr() as *const [u8; 32]) } - } else { - let mut actual_seed = [0u8; 32]; - seed.iter() - .enumerate() - .for_each(|(i, b)| actual_seed[i] = *b); - actual_seed - } -} diff --git a/crates/solis-legacy/src/contracts/account.rs b/crates/solis-legacy/src/contracts/account.rs deleted file mode 100644 index f19a7d9c6..000000000 --- a/crates/solis-legacy/src/contracts/account.rs +++ /dev/null @@ -1,42 +0,0 @@ -use starknet::{ - accounts::{ExecutionEncoding, SingleOwnerAccount}, - core::types::FieldElement, - providers::{jsonrpc::HttpTransport, AnyProvider, JsonRpcClient, Provider}, - signers::{LocalWallet, SigningKey}, -}; - -use url::Url; - -/// Initializes a new account to interact with Starknet. -/// -/// # Arguments -/// -/// * `provider_url` - Starknet provider's url. -/// * `account_address` - Starknet account's address. -/// * `private_key` - Private key associated to the Starknet account. -#[allow(dead_code)] -pub async fn new_account( - provider_url: &str, - account_address: FieldElement, - private_key: FieldElement, -) -> SingleOwnerAccount { - let rpc_url = Url::parse(provider_url).expect("Expecting valid Starknet RPC URL"); - let provider = - AnyProvider::JsonRpcHttp(JsonRpcClient::new(HttpTransport::new(rpc_url.clone()))); - - // TODO: need error instead of expect. - let chain_id = provider - .chain_id() - .await - .expect("couldn't get chain_id from provider"); - - let signer = LocalWallet::from(SigningKey::from_secret_scalar(private_key)); - - SingleOwnerAccount::new( - provider, - signer, - account_address, - chain_id, - ExecutionEncoding::Legacy, - ) -} diff --git a/crates/solis-legacy/src/contracts/executor.rs b/crates/solis-legacy/src/contracts/executor.rs deleted file mode 100644 index e69de29bb..000000000 diff --git a/crates/solis-legacy/src/contracts/mod.rs b/crates/solis-legacy/src/contracts/mod.rs deleted file mode 100644 index df2f73e1e..000000000 --- a/crates/solis-legacy/src/contracts/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod account; -pub mod orderbook; -pub mod starknet_utils; diff --git a/crates/solis-legacy/src/contracts/orderbook.rs b/crates/solis-legacy/src/contracts/orderbook.rs deleted file mode 100644 index 9bc801643..000000000 --- a/crates/solis-legacy/src/contracts/orderbook.rs +++ /dev/null @@ -1,12 +0,0 @@ -use cainome::rs::abigen; -use starknet::{accounts::ConnectedAccount, core::types::FieldElement}; - -abigen!(OrderbookContract, "./artifacts/orderbook.abi.json"); - -#[allow(dead_code)] -pub fn new_orderbook( - contract_address: FieldElement, - account: A, -) -> OrderbookContract { - OrderbookContract::new(contract_address, account) -} diff --git a/crates/solis-legacy/src/contracts/starknet_utils.rs b/crates/solis-legacy/src/contracts/starknet_utils.rs deleted file mode 100644 index 280c9f2e6..000000000 --- a/crates/solis-legacy/src/contracts/starknet_utils.rs +++ /dev/null @@ -1,19 +0,0 @@ -use cainome::rs::abigen; -use starknet::{ - core::types::FieldElement, - providers::{jsonrpc::HttpTransport, AnyProvider, JsonRpcClient}, -}; - -use url::Url; - -abigen!(StarknetUtils, "./artifacts/starknet_utils.json"); -pub fn new_starknet_utils_reader( - contract_address: FieldElement, - provider_url: &str, -) -> StarknetUtilsReader { - let rpc_url = Url::parse(provider_url).expect("Expecting valid Starknet RPC URL"); - let provider = - AnyProvider::JsonRpcHttp(JsonRpcClient::new(HttpTransport::new(rpc_url.clone()))); - - StarknetUtilsReader::new(contract_address, provider) -} diff --git a/crates/solis-legacy/src/hooker.rs b/crates/solis-legacy/src/hooker.rs deleted file mode 100644 index 6c403b3f8..000000000 --- a/crates/solis-legacy/src/hooker.rs +++ /dev/null @@ -1,458 +0,0 @@ -//! Solis hooker on Katana transaction lifecycle. -//! -use crate::contracts::starknet_utils::{ExecutionInfo, U256}; -use async_trait::async_trait; -use cainome::cairo_serde::CairoSerde; -use cainome::rs::abigen; -use katana_core::hooker::{HookerAddresses, KatanaHooker}; -use katana_core::sequencer::KatanaSequencer; -use katana_primitives::chain::ChainId; -use katana_primitives::contract::ContractAddress; -use katana_primitives::transaction::{ExecutableTx, ExecutableTxWithHash, L1HandlerTx}; -use katana_primitives::utils::transaction::compute_l1_message_hash; -use starknet::accounts::Call; -use starknet::core::types::BroadcastedInvokeTransaction; -use starknet::core::types::FieldElement; -use starknet::macros::selector; -use starknet::providers::Provider; -use std::sync::Arc; - -use crate::contracts::orderbook::{OrderV1, RouteType}; -use crate::contracts::starknet_utils::StarknetUtilsReader; -use crate::CHAIN_ID_SOLIS; - -#[allow(dead_code)] -pub enum CancelStatus { - CancelledUser, - CancelledByNewOrder, - CancelledAssetFault, - CancelledOwnership, -} - -impl CancelStatus { - fn to_u32(&self) -> u32 { - match self { - CancelStatus::CancelledUser => 1, - CancelStatus::CancelledByNewOrder => 2, - CancelStatus::CancelledAssetFault => 3, - CancelStatus::CancelledOwnership => 4, - } - } -} - -struct OwnershipVerifier { - token_address: ContractAddress, - token_id: U256, - current_owner: cainome::cairo_serde::ContractAddress, -} - -struct BalanceVerifier { - currency_address: ContractAddress, - offerer: cainome::cairo_serde::ContractAddress, - start_amount: U256, -} - -abigen!(CallContract, "./artifacts/contract.abi.json"); - -/// Hooker struct, with already instanciated contracts/readers -/// to avoid allocating them at each transaction that is being -/// verified. -pub struct SolisHooker { - // Solis interacts with the orderbook only via `L1HandlerTransaction`. Only the - // address is required. - pub orderbook_address: FieldElement, - // TODO: replace this by the Executor Contract object! - pub sn_executor_address: FieldElement, - pub sn_utils_reader: StarknetUtilsReader

, - sequencer: Option>, -} - -impl SolisHooker

{ - /// Verify the ownership of a token - async fn verify_ownership(&self, ownership_verifier: &OwnershipVerifier) -> bool { - let sn_utils_reader_nft_address = StarknetUtilsReader::new( - ownership_verifier.token_address.into(), - self.sn_utils_reader.provider(), - ); - - // check the current owner of the token. - let owner = sn_utils_reader_nft_address - .ownerOf(&ownership_verifier.token_id) - .call() - .await; - - if let Ok(owner_address) = owner { - if owner_address != ownership_verifier.current_owner { - tracing::trace!( - "\nOwner {:?} differs from offerer {:?} ", - owner, - ownership_verifier.current_owner - ); - - println!( - "\nOwner {:?} differs from offerer {:?} ", - owner, ownership_verifier.current_owner - ); - - return false; - } - } - - true - } - - async fn verify_balance(&self, balance_verifier: &BalanceVerifier) -> bool { - let sn_utils_reader_erc20_address = StarknetUtilsReader::new( - balance_verifier.currency_address.into(), - self.sn_utils_reader.provider(), - ); - let allowance = sn_utils_reader_erc20_address - .allowance(&balance_verifier.offerer, &self.sn_executor_address.into()) - .call() - .await; - - if let Ok(allowance) = allowance { - if allowance < balance_verifier.start_amount { - println!( - "\nAllowance {:?} is not enough {:?} for offerer {:?}", - allowance, balance_verifier.start_amount, balance_verifier.offerer - ); - return false; - } - } - - // check the balance - let balance = sn_utils_reader_erc20_address - .balanceOf(&balance_verifier.offerer) - .call() - .await; - if let Ok(balance) = balance { - if balance < balance_verifier.start_amount { - tracing::trace!( - "\nBalance {:?} is not enough {:?} ", - balance, - balance_verifier.start_amount - ); - println!( - "\nBalance {:?} is not enough {:?} ", - balance, balance_verifier.start_amount - ); - return false; - } - } - - true - } - - async fn verify_call(&self, call: &TxCall) -> bool { - let order = match OrderV1::cairo_deserialize(&call.calldata, 0) { - Ok(order) => order, - Err(e) => { - tracing::error!("Fail deserializing OrderV1: {:?}", e); - return false; - } - }; - - // ERC721 to ERC20 - if order.route == RouteType::Erc721ToErc20 { - let token_id = order.token_id.clone().unwrap(); - let n_token_id = U256 { - low: token_id.low, - high: token_id.high, - }; - - let verifier = OwnershipVerifier { - token_address: ContractAddress(order.token_address.into()), - token_id: n_token_id, - current_owner: cainome::cairo_serde::ContractAddress(order.offerer.into()), - }; - - let owner_ship_verification = self.verify_ownership(&verifier).await; - if !owner_ship_verification { - return false; - } - } - - // ERC20 to ERC721 : we check the allowance and the offerer balance. - if order.route == RouteType::Erc20ToErc721 { - if !self - .verify_balance(&BalanceVerifier { - currency_address: ContractAddress(order.currency_address.into()), - offerer: cainome::cairo_serde::ContractAddress(order.offerer.into()), - start_amount: U256 { - low: order.start_amount.low, - high: order.start_amount.high, - }, - }) - .await - { - println!("verify balance for starknet before failed"); - return false; - } - } - return true; - } -} - -impl SolisHooker

{ - /// Initializes a new instance. - pub fn new( - sn_utils_reader: StarknetUtilsReader

, - orderbook_address: FieldElement, - sn_executor_address: FieldElement, - ) -> Self { - Self { - orderbook_address, - sn_utils_reader, - sn_executor_address, - sequencer: None, - } - } - - /// Retrieves a reference to the sequencer. - #[allow(dead_code)] - pub fn sequencer_ref(&self) -> &Arc { - // The expect is used here as it must always be set by Katana core. - // If not set, the merge on Katana may be revised. - self.sequencer - .as_ref() - .expect("Sequencer must be set to get a reference to it") - } - - /// Adds a `L1HandlerTransaction` to the transaction pool that is directed to the - /// orderbook only. - /// `L1HandlerTransaction` is a special type of transaction that can only be - /// sent by the sequencer itself. This transaction is not validated by any account. - /// - /// In the case of Solis, `L1HandlerTransaction` are sent by Solis for two purposes: - /// 1. A message was collected from the L2, and it must be executed. - /// 2. A transaction has been rejected by Solis (asset faults), and the order - /// must then be updated. - /// - /// This function is used for the scenario 2. For this reason, the `from_address` - /// field is automatically filled up by the sequencer to use the executor address - /// deployed on L2 to avoid any attack by other contracts. - /// - /// # Arguments - /// - /// * `selector` - The selector of the recipient contract to execute. - /// * `payload` - The payload of the message. - #[allow(dead_code)] - pub fn add_l1_handler_transaction_for_orderbook( - &self, - selector: FieldElement, - payload: &[FieldElement], - ) { - let to_address = self.orderbook_address; - let from_address = self.sn_executor_address; - let chain_id = ChainId::Id(CHAIN_ID_SOLIS); - - // The nonce is normally used by the messaging contract on Starknet. But in the - // case of those transaction, as they are only sent by Solis itself, we use 0. - // TODO: this value of 0 must be checked by the `l1_handler` function. - let nonce = FieldElement::ZERO; - - // The calldata always starts with the from_address. - let mut calldata: Vec = vec![from_address]; - for p in payload.into_iter() { - calldata.push(*p); - } - - let message_hash = compute_l1_message_hash(from_address, to_address, payload); - - let tx = L1HandlerTx { - nonce, - chain_id, - paid_fee_on_l1: 30000_u128, - version: FieldElement::ZERO, - message_hash, - calldata, - contract_address: ContractAddress(to_address), - entry_point_selector: selector, - }; - - if let Some(seq) = &self.sequencer { - let exe = ExecutableTxWithHash::new_query(ExecutableTx::L1Handler(tx)); - seq.add_transaction_to_pool(exe); - } - } -} - -/// Solis hooker relies on verifiers to inspect and verify -/// the transaction and starknet state before acceptance. -#[async_trait] -impl KatanaHooker for SolisHooker

{ - fn set_sequencer(&mut self, sequencer: Arc) { - self.sequencer = Some(sequencer); - } - - fn set_addresses(&mut self, addresses: HookerAddresses) { - self.orderbook_address = addresses.orderbook_arkchain; - self.sn_executor_address = addresses.executor_starknet; - } - - /// Verifies if the message is directed to the orderbook and comes from - /// the executor contract on L2. - /// - /// Currently, only the `from` and `to` are checked. - /// More checks may be added on the selector, and the data. - async fn verify_message_to_appchain( - &self, - from: FieldElement, - to: FieldElement, - _selector: FieldElement, - ) -> bool { - // For now, only the from/to are checked. - from == self.sn_executor_address && to == self.orderbook_address - } - - /// Verifies an invoke transaction that is: - /// 1. Directed to the orderbook only. - /// 2. With the selector `create_order` only as the fulfill - /// is verified by `verify_message_to_starknet_before_tx`. - async fn verify_invoke_tx_before_pool( - &self, - transaction: BroadcastedInvokeTransaction, - ) -> bool { - let calls = match Vec::::cairo_deserialize(&transaction.calldata, 0) { - Ok(calls) => calls, - Err(e) => { - tracing::error!("Fail deserializing OrderV1: {:?}", e); - return false; - } - }; - - for call in calls { - if call.selector != selector!("create_order") { - continue; - } - - if !self.verify_call(&call).await { - return false; - } - - // TODO: check assets on starknet. - // TODO: if not valid, in some cases we want to send L1HandlerTransaction - // to change the status of the order. (entrypoint to be written). - } - true - } - - async fn verify_tx_for_starknet(&self, call: Call) -> bool { - println!("verify message to starknet before tx: {:?}", call); - if call.selector != selector!("fulfill_order") { - return true; - } - println!("verify message to starknet before tx after"); - - let execution_info = match ExecutionInfo::cairo_deserialize(&call.calldata, 0) { - Ok(execution_info) => execution_info, - Err(e) => { - tracing::error!("Fail deserializing ExecutionInfo: {:?}", e); - return false; - } - }; - - let verifier = OwnershipVerifier { - token_address: ContractAddress(execution_info.nft_address.into()), - token_id: execution_info.nft_token_id, - current_owner: cainome::cairo_serde::ContractAddress(execution_info.nft_from.into()), - }; - - let owner_ship_verification = self.verify_ownership(&verifier).await; - if !owner_ship_verification { - // rollback the status - let status = CancelStatus::CancelledOwnership; - - self.add_l1_handler_transaction_for_orderbook( - selector!("rollback_status_order"), - &[execution_info.order_hash, status.to_u32().into()], - ); - return false; - } - - if !self - .verify_balance(&BalanceVerifier { - currency_address: ContractAddress(execution_info.payment_currency_address.into()), - offerer: cainome::cairo_serde::ContractAddress(execution_info.nft_to.into()), - start_amount: U256 { - low: execution_info.payment_amount.low, - high: execution_info.payment_amount.high, - }, - }) - .await - { - // rollback the status - let status = CancelStatus::CancelledAssetFault; - - self.add_l1_handler_transaction_for_orderbook( - selector!("rollback_status_order"), - &[execution_info.order_hash, status.to_u32().into()], - ); - return false; - } - - true - } - - async fn on_starknet_tx_failed(&self, call: Call) { - println!("Starknet tx failed: {:?}", call); - - let execution_info = match ExecutionInfo::cairo_deserialize(&call.calldata, 0) { - Ok(execution_info) => execution_info, - Err(e) => { - tracing::error!("Fail deserializing ExecutionInfo: {:?}", e); - return; - } - }; - - // rollback the status - self.add_l1_handler_transaction_for_orderbook( - selector!("rollback_status_order"), - &[execution_info.order_hash], - ); - } -} - -#[cfg(test)] -mod test { - use super::*; - use starknet::macros::{felt, selector}; - - #[test] - fn test_calldata_calls_parsing_new_encoding() { - // Calldata for a transaction to starkgate: - // Tx hash Goerli: 0x78140a4777bdf508feec62485c2d49b90b8346875c19470790935bcfbb9594 - let data = vec![ - FieldElement::ONE, - // to (starkgate). - felt!("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"), - // selector (transfert). - felt!("0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e"), - // data offset. - felt!("0x0"), - // data len. - felt!("0x0"), - // Calldata len. - FieldElement::THREE, - felt!("0x06cdcce7333a7143ad0aebbaffe54a809cc53b65c0936ecfbebaecc0de099e8e"), - felt!("0x071afd498d0000"), - felt!("0x00"), - ]; - - let calls = match Vec::::cairo_deserialize(&data, 0) { - Ok(calls) => calls, - Err(e) => { - tracing::error!("Fail deserializing OrderV1: {:?}", e); - Vec::new() - } - }; - - assert_eq!(calls.len(), 1); - assert_eq!( - calls[0].to, - felt!("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").into() - ); - assert_eq!(calls[0].selector, selector!("transfer")); - } -} diff --git a/crates/solis-legacy/src/main.rs b/crates/solis-legacy/src/main.rs deleted file mode 100644 index c5dbafff2..000000000 --- a/crates/solis-legacy/src/main.rs +++ /dev/null @@ -1,198 +0,0 @@ -// use anyhow::Result; -// use clap::Parser; -// use console::Style; - -// use katana_core::hooker::KatanaHooker; -// use katana_core::sequencer::KatanaSequencer; -// use katana_rpc::{spawn, NodeHandle}; - -// use starknet::core::types::FieldElement; -// use std::sync::Arc; -// use tokio::signal::ctrl_c; -// use tokio::sync::RwLock as AsyncRwLock; -// use tracing_subscriber::fmt; - -use std::io; -use std::sync::Arc; - -use clap::{CommandFactory, Parser}; -use clap_complete::{generate, Shell}; -use console::Style; -use katana_core::constants::{ - ERC20_CONTRACT_CLASS_HASH, FEE_TOKEN_ADDRESS, UDC_ADDRESS, UDC_CLASS_HASH, -}; -use katana_core::hooker::KatanaHooker; -use katana_core::sequencer::KatanaSequencer; -use katana_rpc::{spawn, NodeHandle}; -use starknet::core::types::FieldElement; -use tokio::signal::ctrl_c; -use tokio::sync::RwLock as AsyncRwLock; -use tracing::info; - -use crate::hooker::SolisHooker; - -mod args; - -use args::Commands::Completions; -use args::KatanaArgs; - -//mod args; -mod contracts; -mod hooker; -mod solis_args; - -// Chain ID: 'SOLIS' cairo short string. -pub const CHAIN_ID_SOLIS: FieldElement = FieldElement::from_mont([ - 18446732623703627169, - 18446744073709551615, - 18446744073709551615, - 576266102202707888, -]); - -#[tokio::main] -async fn main() -> Result<(), Box> { - dotenv::dotenv().ok(); - - let config = KatanaArgs::parse(); - config.init_logging()?; - - if let Some(command) = config.command { - match command { - Completions { shell } => { - print_completion(shell); - return Ok(()); - } - } - } - - let server_config = config.server_config(); - let sequencer_config = config.sequencer_config(); - let starknet_config = config.starknet_config(); - - // ** SOLIS - let sn_utils_reader = contracts::starknet_utils::new_starknet_utils_reader( - FieldElement::ZERO, - &sequencer_config.messaging.clone().unwrap().rpc_url, - ); - - let executor_address = FieldElement::ZERO; - let orderbook_address = FieldElement::ZERO; - - let hooker = Arc::new(AsyncRwLock::new(SolisHooker::new( - sn_utils_reader, - orderbook_address, - executor_address, - ))); - // ** - - let sequencer = Arc::new( - KatanaSequencer::new(sequencer_config, starknet_config, hooker.clone()) - .await - .expect("Failed to start sequencer"), - ); - let NodeHandle { addr, handle, .. } = spawn(Arc::clone(&sequencer), server_config).await?; - - // ** SOLIS - // Important to set the sequencer reference in the hooker, to allow the hooker - // to send `L1HandlerTransaction` to the orderbook. - hooker.write().await.set_sequencer(sequencer.clone()); - // ** - - if !config.silent { - let mut accounts = sequencer.backend.accounts.iter().peekable(); - let account_class_hash = accounts.peek().unwrap().class_hash; - - if config.json_log { - info!( - "{}", - serde_json::json!({ - "accounts": accounts.map(|a| serde_json::json!(a)).collect::>(), - "seed": format!("{}", config.starknet.seed), - "address": format!("{addr}"), - }) - ) - } else { - let accounts = accounts - .map(|a| format!("{a}")) - .collect::>() - .join("\n"); - print_intro( - accounts, - config.starknet.seed.clone(), - format!( - "🚀 JSON-RPC server started: {}", - Style::new().red().apply_to(format!("http://{addr}")) - ), - format!("{:#064x}", account_class_hash), - ); - } - } - - // Wait until Ctrl + C is pressed, then shutdown - ctrl_c().await?; - handle.stop()?; - - Ok(()) -} - -fn print_completion(shell: Shell) { - let mut command = KatanaArgs::command(); - let name = command.get_name().to_string(); - generate(shell, &mut command, name, &mut io::stdout()); -} - -fn print_intro(accounts: String, seed: String, address: String, account_class_hash: String) { - println!( - "{}", - Style::new().blue().apply_to( - r" - - ___ ___ | (_)___ -/ __|/ _ \| | / __| -\__ \ (_) | | \__ \ -|___/\___/|_|_|___/ -" - ) - ); - - println!( - r" -PREDEPLOYED CONTRACTS -================== - -| Contract | Fee Token -| Address | {} -| Class Hash | {:#064x} - -| Contract | Universal Deployer -| Address | {} -| Class Hash | {:#064x} - -| Contract | Account Contract -| Class Hash | {} - ", - *FEE_TOKEN_ADDRESS, - *ERC20_CONTRACT_CLASS_HASH, - *UDC_ADDRESS, - *UDC_CLASS_HASH, - account_class_hash - ); - - println!( - r" -PREFUNDED ACCOUNTS -================== -{accounts} - " - ); - - println!( - r" -ACCOUNTS SEED -============= -{seed} - " - ); - - println!("\n{address}\n\n"); -} diff --git a/crates/solis-legacy/src/solis_args.rs b/crates/solis-legacy/src/solis_args.rs deleted file mode 100644 index de1f50bd7..000000000 --- a/crates/solis-legacy/src/solis_args.rs +++ /dev/null @@ -1,14 +0,0 @@ -// use clap::Args; - -// #[derive(Debug, Args, Clone)] -// pub struct SolisOptions { -// #[arg(short, long)] -// #[arg(help = "Orderbook address: The address of the orderbook contract (deployed on Solis).")] -// pub orderbook_address: String, - -// #[arg(short, long)] -// #[arg( -// help = "Executor address: The address of the Ark executor contract (deployed on Starknet)." -// )] -// pub executor_address: String, -// } diff --git a/crates/solis/.gitignore b/crates/solis/.gitignore deleted file mode 100644 index 2316af87a..000000000 --- a/crates/solis/.gitignore +++ /dev/null @@ -1 +0,0 @@ -messaging.local.json diff --git a/crates/solis/Cargo.toml b/crates/solis/Cargo.toml deleted file mode 100644 index b2079cd76..000000000 --- a/crates/solis/Cargo.toml +++ /dev/null @@ -1,50 +0,0 @@ -[package] -description = "Modified katana to match ArkProject requirement." -edition = "2021" -license = "Apache-2.0" -name = "solis" -repository = "https://github.com/ArkProjectNFTs/dojo" -version = "0.7.0-alpha-1" - -[dependencies] -alloy-primitives = "0.7.1" -anyhow = "1.0.80" -async-trait = "0.1.57" -cainome = { git = "https://github.com/cartridge-gg/cainome", tag = "v0.2.6", features = [ - "abigen-rs", -] } -cfg-if = "1.0.0" -clap = { version = "4.5.4", features = ["derive"] } -clap_complete = "4.3" -console = "0.15.7" -common = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.7.0.6-solis", package = "common" } -dojo-metrics = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.7.0.6-solis", package = "dojo-metrics" } -dotenv = "0.15.0" -katana-core = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.7.0.6-solis", package = "katana-core", default-features = false } -katana-executor = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.7.0.6-solis", package = "katana-executor", default-features = false } -katana-primitives = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.7.0.6-solis", package = "katana-primitives" } -katana-rpc-api = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.7.0.6-solis", package = "katana-rpc-api" } -katana-rpc = { git = "https://github.com/ArkProjectNFTs/dojo", tag = "v0.7.0.6-solis", package = "katana-rpc" } - -serde_json = "1.0.97" -shellexpand = "3.1.0" -starknet = "0.9.0" -starknet_api = "0.10.0" -tokio = { version = "1.32.0", features = ["full"] } -tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] } -tracing = "0.1.34" -url = { version = "2.4.0", features = ["serde"] } - -[dev-dependencies] -assert_matches = "1.5.0" - -[features] -default = ["blockifier", "jemalloc", "messaging"] - -blockifier = ["katana-executor/blockifier"] -# Disable until SIR support Cairo 2.6.3 -# sir = ["katana-executor/sir"] - -jemalloc = ["dojo-metrics/jemalloc"] -messaging = ["katana-core/messaging"] -starknet-messaging = ["katana-core/starknet-messaging", "messaging"] diff --git a/crates/solis/src/args.rs b/crates/solis/src/args.rs deleted file mode 100644 index 4bb66b2d7..000000000 --- a/crates/solis/src/args.rs +++ /dev/null @@ -1,359 +0,0 @@ -//! Katana binary executable. -//! -//! ## Feature Flags -//! -//! - `jemalloc`: Uses [jemallocator](https://github.com/tikv/jemallocator) as the global allocator. -//! This is **not recommended on Windows**. See [here](https://rust-lang.github.io/rfcs/1974-global-allocators.html#jemalloc) -//! for more info. -//! - `jemalloc-prof`: Enables [jemallocator's](https://github.com/tikv/jemallocator) heap profiling -//! and leak detection functionality. See [jemalloc's opt.prof](https://jemalloc.net/jemalloc.3.html#opt.prof) -//! documentation for usage details. This is **not recommended on Windows**. See [here](https://rust-lang.github.io/rfcs/1974-global-allocators.html#jemalloc) -//! for more info. - -use std::env; -use std::net::SocketAddr; -use std::path::PathBuf; - -use alloy_primitives::U256; -use clap::{Args, Parser, Subcommand}; -use clap_complete::Shell; -use common::parse::parse_socket_address; -use katana_core::backend::config::{Environment, StarknetConfig}; -use katana_core::constants::{ - DEFAULT_ETH_L1_GAS_PRICE, DEFAULT_INVOKE_MAX_STEPS, DEFAULT_SEQUENCER_ADDRESS, - DEFAULT_STRK_L1_GAS_PRICE, DEFAULT_VALIDATE_MAX_STEPS, -}; -use katana_core::sequencer::SequencerConfig; -use katana_primitives::block::GasPrices; -use katana_primitives::chain::ChainId; -use katana_primitives::genesis::allocation::DevAllocationsGenerator; -use katana_primitives::genesis::constant::DEFAULT_PREFUNDED_ACCOUNT_BALANCE; -use katana_primitives::genesis::Genesis; -use katana_rpc::config::ServerConfig; -use katana_rpc_api::ApiKind; -use tracing::Subscriber; -use tracing_subscriber::{fmt, EnvFilter}; -use url::Url; - -use crate::utils::{parse_genesis, parse_seed}; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -#[command(propagate_version = true)] -pub struct KatanaArgs { - #[arg(long)] - #[arg(help = "Don't print anything on startup.")] - pub silent: bool, - - #[arg(long)] - #[arg(conflicts_with = "block_time")] - #[arg(help = "Disable auto and interval mining, and mine on demand instead via an endpoint.")] - pub no_mining: bool, - - #[arg(short, long)] - #[arg(value_name = "MILLISECONDS")] - #[arg(help = "Block time in milliseconds for interval mining.")] - pub block_time: Option, - - #[arg(long)] - #[arg(value_name = "PATH")] - #[arg(help = "Directory path of the database to initialize from.")] - #[arg( - long_help = "Directory path of the database to initialize from. The path must either \ - be an empty directory or a directory which already contains a previously \ - initialized Katana database." - )] - pub db_dir: Option, - - #[arg(long)] - #[arg(value_name = "URL")] - #[arg(help = "The Starknet RPC provider to fork the network from.")] - pub rpc_url: Option, - - #[arg(long)] - pub dev: bool, - - #[arg(long)] - #[arg(help = "Output logs in JSON format.")] - pub json_log: bool, - - /// Enable Prometheus metrics. - /// - /// The metrics will be served at the given interface and port. - #[arg(long, value_name = "SOCKET", value_parser = parse_socket_address, help_heading = "Metrics")] - pub metrics: Option, - - #[arg(long)] - #[arg(requires = "rpc_url")] - #[arg(value_name = "BLOCK_NUMBER")] - #[arg(help = "Fork the network at a specific block.")] - pub fork_block_number: Option, - - #[cfg(feature = "messaging")] - #[arg(long)] - #[arg(value_name = "PATH")] - #[arg(value_parser = katana_core::service::messaging::MessagingConfig::parse)] - #[arg(help = "Configure the messaging with an other chain.")] - #[arg( - long_help = "Configure the messaging to allow Katana listening/sending messages on a \ - settlement chain that can be Ethereum or an other Starknet sequencer. \ - The configuration file details and examples can be found here: https://book.dojoengine.org/toolchain/katana/reference#messaging" - )] - pub messaging: Option, - - #[command(flatten)] - #[command(next_help_heading = "Server options")] - pub server: ServerOptions, - - #[command(flatten)] - #[command(next_help_heading = "Starknet options")] - pub starknet: StarknetOptions, - - #[command(subcommand)] - pub command: Option, -} - -#[derive(Debug, Subcommand)] -pub enum Commands { - #[command(about = "Generate shell completion file for specified shell")] - Completions { shell: Shell }, -} - -#[derive(Debug, Args, Clone)] -pub struct ServerOptions { - #[arg(short, long)] - #[arg(default_value = "7777")] - #[arg(help = "Port number to listen on.")] - pub port: u16, - - #[arg(long)] - #[arg(help = "The IP address the server will listen on.")] - pub host: Option, - - #[arg(long)] - #[arg(default_value = "100")] - #[arg(help = "Maximum number of concurrent connections allowed.")] - pub max_connections: u32, - - #[arg(long)] - #[arg(value_delimiter = ',')] - #[arg(help = "Enables the CORS layer and sets the allowed origins, separated by commas.")] - pub allowed_origins: Option>, -} - -#[derive(Debug, Args, Clone)] -pub struct StarknetOptions { - #[arg(long)] - #[arg(default_value = "0")] - #[arg(help = "Specify the seed for randomness of accounts to be predeployed.")] - pub seed: String, - - #[arg(long = "accounts")] - #[arg(value_name = "NUM")] - #[arg(default_value = "10")] - #[arg(help = "Number of pre-funded accounts to generate.")] - pub total_accounts: u16, - - #[arg(long)] - #[arg(help = "Disable charging fee when executing transactions.")] - pub disable_fee: bool, - - #[arg(long)] - #[arg(help = "Disable validation when executing transactions.")] - pub disable_validate: bool, - - #[command(flatten)] - #[command(next_help_heading = "Environment options")] - pub environment: EnvironmentOptions, - - #[arg(long)] - #[arg(value_parser = parse_genesis)] - #[arg(conflicts_with_all(["rpc_url", "seed", "total_accounts"]))] - pub genesis: Option, -} - -#[derive(Debug, Args, Clone)] -pub struct EnvironmentOptions { - #[arg(long)] - #[arg(help = "The chain ID.")] - #[arg( - long_help = "The chain ID. If a raw hex string (`0x` prefix) is provided, then it'd \ - used as the actual chain ID. Otherwise, it's represented as the raw \ - ASCII values. It must be a valid Cairo short string." - )] - #[arg(default_value = "SOLIS")] - #[arg(value_parser = ChainId::parse)] - pub chain_id: ChainId, - - #[arg(long)] - #[arg(help = "The maximum number of steps available for the account validation logic.")] - #[arg(default_value_t = DEFAULT_VALIDATE_MAX_STEPS)] - pub validate_max_steps: u32, - - #[arg(long)] - #[arg(help = "The maximum number of steps available for the account execution logic.")] - #[arg(default_value_t = DEFAULT_INVOKE_MAX_STEPS)] - pub invoke_max_steps: u32, - - #[arg(long = "eth-gas-price")] - #[arg(conflicts_with = "genesis")] - #[arg(help = "The L1 ETH gas price. (denominated in wei)")] - #[arg(default_value_t = DEFAULT_ETH_L1_GAS_PRICE)] - pub l1_eth_gas_price: u128, - - #[arg(long = "strk-gas-price")] - #[arg(conflicts_with = "genesis")] - #[arg(help = "The L1 STRK gas price. (denominated in fri)")] - #[arg(default_value_t = DEFAULT_STRK_L1_GAS_PRICE)] - pub l1_strk_gas_price: u128, -} - -impl KatanaArgs { - pub fn init_logging(&self) -> Result<(), Box> { - const DEFAULT_LOG_FILTER: &str = "info,executor=trace,forked_backend=trace,server=debug,\ - katana_core=trace,blockifier=off,jsonrpsee_server=off,\ - hyper=off,messaging=debug,node=error"; - - let builder = fmt::Subscriber::builder().with_env_filter( - EnvFilter::try_from_default_env().or(EnvFilter::try_new(DEFAULT_LOG_FILTER))?, - ); - - let subscriber: Box = if self.json_log { - Box::new(builder.json().finish()) - } else { - Box::new(builder.finish()) - }; - - Ok(tracing::subscriber::set_global_default(subscriber)?) - } - - pub fn sequencer_config(&self) -> SequencerConfig { - SequencerConfig { - block_time: self.block_time, - no_mining: self.no_mining, - #[cfg(feature = "messaging")] - messaging: self.messaging.clone(), - } - } - - pub fn server_config(&self) -> ServerConfig { - let mut apis = vec![ - ApiKind::Starknet, - ApiKind::Katana, - ApiKind::Torii, - ApiKind::Saya, - ApiKind::Solis, - ]; - // only enable `katana` API in dev mode - if self.dev { - apis.push(ApiKind::Dev); - } - - let rpc_user = env::var("RPC_USER").unwrap_or_else(|_| "userDefault".to_string()); - let rpc_password = - env::var("RPC_PASSWORD").unwrap_or_else(|_| "passwordDefault".to_string()); - ServerConfig { - apis, - port: self.server.port, - host: self.server.host.clone().unwrap_or("0.0.0.0".into()), - max_connections: self.server.max_connections, - allowed_origins: self.server.allowed_origins.clone(), - rpc_user, - rpc_password, - } - } - - pub fn starknet_config(&self) -> StarknetConfig { - let genesis = match self.starknet.genesis.clone() { - Some(genesis) => genesis, - None => { - let gas_prices = GasPrices { - eth: self.starknet.environment.l1_eth_gas_price, - strk: self.starknet.environment.l1_strk_gas_price, - }; - - let accounts = DevAllocationsGenerator::new(self.starknet.total_accounts) - .with_seed(parse_seed(&self.starknet.seed)) - .with_balance(U256::from(DEFAULT_PREFUNDED_ACCOUNT_BALANCE)) - .generate(); - - let mut genesis = Genesis { - gas_prices, - sequencer_address: *DEFAULT_SEQUENCER_ADDRESS, - ..Default::default() - }; - - genesis.extend_allocations(accounts.into_iter().map(|(k, v)| (k, v.into()))); - genesis - } - }; - - StarknetConfig { - disable_fee: self.starknet.disable_fee, - disable_validate: self.starknet.disable_validate, - fork_rpc_url: self.rpc_url.clone(), - fork_block_number: self.fork_block_number, - env: Environment { - chain_id: self.starknet.environment.chain_id, - invoke_max_steps: self.starknet.environment.invoke_max_steps, - validate_max_steps: self.starknet.environment.validate_max_steps, - }, - db_dir: self.db_dir.clone(), - genesis, - } - } -} - -// #[cfg(test)] -// mod test { -// use super::*; - -// #[test] -// fn test_starknet_config_default() { -// let args = KatanaArgs::parse_from(["katana"]); -// let config = args.starknet_config(); - -// assert!(!config.disable_fee); -// assert!(!config.disable_validate); -// assert_eq!(config.fork_rpc_url, None); -// assert_eq!(config.fork_block_number, None); -// assert_eq!(config.env.chain_id, ChainId::parse("KATANA").unwrap()); -// assert_eq!(config.env.invoke_max_steps, DEFAULT_INVOKE_MAX_STEPS); -// assert_eq!(config.env.validate_max_steps, DEFAULT_VALIDATE_MAX_STEPS); -// assert_eq!(config.db_dir, None); -// assert_eq!(config.genesis.gas_prices.eth, DEFAULT_ETH_L1_GAS_PRICE); -// assert_eq!(config.genesis.gas_prices.strk, DEFAULT_STRK_L1_GAS_PRICE); -// assert_eq!(config.genesis.sequencer_address, *DEFAULT_SEQUENCER_ADDRESS); -// } - -// #[test] -// fn test_starknet_config_custom() { -// let args = KatanaArgs::parse_from([ -// "katana", -// "--disable-fee", -// "--disable-validate", -// "--chain-id", -// "SN_GOERLI", -// "--invoke-max-steps", -// "200", -// "--validate-max-steps", -// "100", -// "--db-dir", -// "/path/to/db", -// "--eth-gas-price", -// "10", -// "--strk-gas-price", -// "20", -// ]); -// let config = args.starknet_config(); - -// assert!(config.disable_fee); -// assert!(config.disable_validate); -// assert_eq!(config.env.chain_id, ChainId::GOERLI); -// assert_eq!(config.env.invoke_max_steps, 200); -// assert_eq!(config.env.validate_max_steps, 100); -// assert_eq!(config.db_dir, Some(PathBuf::from("/path/to/db"))); -// assert_eq!(config.genesis.gas_prices.eth, 10); -// assert_eq!(config.genesis.gas_prices.strk, 20); -// } -// } diff --git a/crates/solis/src/contracts/account.rs b/crates/solis/src/contracts/account.rs deleted file mode 100644 index f19a7d9c6..000000000 --- a/crates/solis/src/contracts/account.rs +++ /dev/null @@ -1,42 +0,0 @@ -use starknet::{ - accounts::{ExecutionEncoding, SingleOwnerAccount}, - core::types::FieldElement, - providers::{jsonrpc::HttpTransport, AnyProvider, JsonRpcClient, Provider}, - signers::{LocalWallet, SigningKey}, -}; - -use url::Url; - -/// Initializes a new account to interact with Starknet. -/// -/// # Arguments -/// -/// * `provider_url` - Starknet provider's url. -/// * `account_address` - Starknet account's address. -/// * `private_key` - Private key associated to the Starknet account. -#[allow(dead_code)] -pub async fn new_account( - provider_url: &str, - account_address: FieldElement, - private_key: FieldElement, -) -> SingleOwnerAccount { - let rpc_url = Url::parse(provider_url).expect("Expecting valid Starknet RPC URL"); - let provider = - AnyProvider::JsonRpcHttp(JsonRpcClient::new(HttpTransport::new(rpc_url.clone()))); - - // TODO: need error instead of expect. - let chain_id = provider - .chain_id() - .await - .expect("couldn't get chain_id from provider"); - - let signer = LocalWallet::from(SigningKey::from_secret_scalar(private_key)); - - SingleOwnerAccount::new( - provider, - signer, - account_address, - chain_id, - ExecutionEncoding::Legacy, - ) -} diff --git a/crates/solis/src/contracts/executor.rs b/crates/solis/src/contracts/executor.rs deleted file mode 100644 index e69de29bb..000000000 diff --git a/crates/solis/src/contracts/mod.rs b/crates/solis/src/contracts/mod.rs deleted file mode 100644 index df2f73e1e..000000000 --- a/crates/solis/src/contracts/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod account; -pub mod orderbook; -pub mod starknet_utils; diff --git a/crates/solis/src/contracts/orderbook.rs b/crates/solis/src/contracts/orderbook.rs deleted file mode 100644 index 9bc801643..000000000 --- a/crates/solis/src/contracts/orderbook.rs +++ /dev/null @@ -1,12 +0,0 @@ -use cainome::rs::abigen; -use starknet::{accounts::ConnectedAccount, core::types::FieldElement}; - -abigen!(OrderbookContract, "./artifacts/orderbook.abi.json"); - -#[allow(dead_code)] -pub fn new_orderbook( - contract_address: FieldElement, - account: A, -) -> OrderbookContract { - OrderbookContract::new(contract_address, account) -} diff --git a/crates/solis/src/contracts/starknet_utils.rs b/crates/solis/src/contracts/starknet_utils.rs deleted file mode 100644 index 280c9f2e6..000000000 --- a/crates/solis/src/contracts/starknet_utils.rs +++ /dev/null @@ -1,19 +0,0 @@ -use cainome::rs::abigen; -use starknet::{ - core::types::FieldElement, - providers::{jsonrpc::HttpTransport, AnyProvider, JsonRpcClient}, -}; - -use url::Url; - -abigen!(StarknetUtils, "./artifacts/starknet_utils.json"); -pub fn new_starknet_utils_reader( - contract_address: FieldElement, - provider_url: &str, -) -> StarknetUtilsReader { - let rpc_url = Url::parse(provider_url).expect("Expecting valid Starknet RPC URL"); - let provider = - AnyProvider::JsonRpcHttp(JsonRpcClient::new(HttpTransport::new(rpc_url.clone()))); - - StarknetUtilsReader::new(contract_address, provider) -} diff --git a/crates/solis/src/hooker.rs b/crates/solis/src/hooker.rs deleted file mode 100644 index 72c67a50c..000000000 --- a/crates/solis/src/hooker.rs +++ /dev/null @@ -1,579 +0,0 @@ -//! Solis hooker on Katana transaction lifecycle. -//! -use crate::contracts::starknet_utils::{ExecutionInfo, U256}; -use async_trait::async_trait; -use cainome::cairo_serde::CairoSerde; -use cainome::rs::abigen; -use katana_core::hooker::{HookerAddresses, KatanaHooker}; -use katana_core::sequencer::KatanaSequencer; -use katana_executor::ExecutorFactory; - -use katana_primitives::chain::ChainId; -use katana_primitives::contract::ContractAddress; -use katana_primitives::transaction::{ExecutableTx, ExecutableTxWithHash, L1HandlerTx}; -use katana_primitives::utils::transaction::compute_l1_message_hash; -use serde_json::json; -use serde_json::Value; -use starknet::accounts::Call; -use starknet::core::types::BroadcastedInvokeTransaction; -use starknet::core::types::FieldElement; -use starknet::macros::selector; -use starknet::providers::Provider; -use std::fs::File; -use std::fs::OpenOptions; -use std::io::Read; -use std::io::Write; -use std::path::Path; -use std::sync::Arc; - -const FILE_PATH_ADDRESSES: &str = "addresses.json"; - -use crate::contracts::orderbook::{OrderV1, RouteType}; -use crate::contracts::starknet_utils::StarknetUtilsReader; -use crate::CHAIN_ID_SOLIS; -use tracing::info; - -#[allow(dead_code)] -pub enum CancelStatus { - CancelledUser, - CancelledByNewOrder, - CancelledAssetFault, - CancelledOwnership, -} - -impl CancelStatus { - fn to_u32(&self) -> u32 { - match self { - CancelStatus::CancelledUser => 1, - CancelStatus::CancelledByNewOrder => 2, - CancelStatus::CancelledAssetFault => 3, - CancelStatus::CancelledOwnership => 4, - } - } -} - -struct OwnershipVerifier { - token_address: ContractAddress, - token_id: U256, - current_owner: cainome::cairo_serde::ContractAddress, -} - -struct BalanceVerifier { - currency_address: ContractAddress, - offerer: cainome::cairo_serde::ContractAddress, - start_amount: U256, -} - -abigen!(CallContract, "./artifacts/contract.abi.json"); - -/// Hooker struct, with already instanciated contracts/readers -/// to avoid allocating them at each transaction that is being -/// verified. -pub struct SolisHooker { - // Solis interacts with the orderbook only via `L1HandlerTransaction`. Only the - // address is required. - pub orderbook_address: FieldElement, - // TODO: replace this by the Executor Contract object! - pub sn_executor_address: FieldElement, - pub sn_utils_reader: StarknetUtilsReader

, - sequencer: Option>>, -} - -impl - SolisHooker -{ - /// Verify the ownership of a token - async fn verify_ownership(&self, ownership_verifier: &OwnershipVerifier) -> bool { - let sn_utils_reader_nft_address = StarknetUtilsReader::new( - ownership_verifier.token_address.into(), - self.sn_utils_reader.provider(), - ); - - // check the current owner of the token. - let owner = sn_utils_reader_nft_address - .ownerOf(&ownership_verifier.token_id) - .call() - .await; - - if let Ok(owner_address) = owner { - if owner_address != ownership_verifier.current_owner { - tracing::trace!( - "\nOwner {:?} differs from offerer {:?} ", - owner, - ownership_verifier.current_owner - ); - - println!( - "\nOwner {:?} differs from offerer {:?} ", - owner, ownership_verifier.current_owner - ); - - return false; - } - } - - true - } - - async fn verify_balance(&self, balance_verifier: &BalanceVerifier) -> bool { - info!("HOOKER: Verify Balance"); - - let sn_utils_reader_erc20_address = StarknetUtilsReader::new( - balance_verifier.currency_address.into(), - self.sn_utils_reader.provider(), - ); - let allowance = sn_utils_reader_erc20_address - .allowance(&balance_verifier.offerer, &self.sn_executor_address.into()) - .call() - .await; - - info!( - "HOOKER: Verify Balance allowance {:?}, amount {:?}", - allowance, balance_verifier.start_amount - ); - - if let Ok(allowance) = allowance { - if allowance < balance_verifier.start_amount { - println!( - "\nAllowance {:?} is not enough {:?} for offerer {:?}", - allowance, balance_verifier.start_amount, balance_verifier.offerer - ); - return false; - } - } - - // check the balance - let balance = sn_utils_reader_erc20_address - .balanceOf(&balance_verifier.offerer) - .call() - .await; - if let Ok(balance) = balance { - if balance < balance_verifier.start_amount { - tracing::trace!( - "\nBalance {:?} is not enough {:?} ", - balance, - balance_verifier.start_amount - ); - println!( - "\nBalance {:?} is not enough {:?} ", - balance, balance_verifier.start_amount - ); - return false; - } - } - - true - } - - async fn verify_call(&self, call: &TxCall) -> bool { - let order = match OrderV1::cairo_deserialize(&call.calldata, 0) { - Ok(order) => order, - Err(e) => { - tracing::error!("Fail deserializing OrderV1: {:?}", e); - return false; - } - }; - - // ERC721 to ERC20 - if order.route == RouteType::Erc721ToErc20 { - let token_id = order.token_id.clone().unwrap(); - let n_token_id = U256 { - low: token_id.low, - high: token_id.high, - }; - - let verifier = OwnershipVerifier { - token_address: ContractAddress(order.token_address.into()), - token_id: n_token_id, - current_owner: cainome::cairo_serde::ContractAddress(order.offerer.into()), - }; - - let owner_ship_verification = self.verify_ownership(&verifier).await; - if !owner_ship_verification { - return false; - } - } - - // ERC20 to ERC721 : we check the allowance and the offerer balance. - if order.route == RouteType::Erc20ToErc721 { - if !self - .verify_balance(&BalanceVerifier { - currency_address: ContractAddress(order.currency_address.into()), - offerer: cainome::cairo_serde::ContractAddress(order.offerer.into()), - start_amount: U256 { - low: order.start_amount.low, - high: order.start_amount.high, - }, - }) - .await - { - println!("verify balance for starknet before failed"); - return false; - } - } - return true; - } -} - -impl - SolisHooker -{ - fn get_addresses_from_file() -> Result<(FieldElement, FieldElement), Box> - { - let mut file = match File::open(FILE_PATH_ADDRESSES) { - Ok(file) => file, - Err(_) => return Err("File not found".into()), - }; - - let mut contents = String::new(); - file.read_to_string(&mut contents)?; - - let v: Value = match serde_json::from_str(&contents) { - Ok(value) => value, - Err(_) => return Err("Error parsing JSON".into()), - }; - - let orderbook_address = match v["orderbook_address"].as_str() { - Some(address) => address, - None => return Err("orderbook_address key not found in JSON".into()), - }; - - let sn_executor_address = match v["sn_executor_address"].as_str() { - Some(address) => address, - None => return Err("sn_executor_address key not found in JSON".into()), - }; - - let orderbook_address = match FieldElement::from_hex_be(&orderbook_address[2..]) { - Ok(val) => FieldElement::from_dec_str(&val.to_string()), - Err(_) => return Err("Failed to parse orderbook_address".into()), - }; - - let sn_executor_address = match FieldElement::from_hex_be(&sn_executor_address[2..]) { - Ok(val) => FieldElement::from_dec_str(&val.to_string()), - Err(_) => return Err("Failed to parse sn_executor_address".into()), - }; - - println!( - "Addresses loaded from file: {:?}, {:?}", - orderbook_address, sn_executor_address - ); - Ok((orderbook_address?, sn_executor_address?)) - } - - /// Initializes a new instance. - pub fn new( - sn_utils_reader: StarknetUtilsReader

, - orderbook_address: FieldElement, - sn_executor_address: FieldElement, - ) -> Self { - let (orderbook_address, sn_executor_address) = if orderbook_address == FieldElement::ZERO - && sn_executor_address == FieldElement::ZERO - { - match Self::get_addresses_from_file() { - Ok((orderbook, executor)) => (orderbook, executor), - Err(e) => { - eprintln!("Error reading addresses from file: {}", e); - (orderbook_address, sn_executor_address) - } - } - } else { - (orderbook_address, sn_executor_address) - }; - - Self { - orderbook_address, - sn_utils_reader, - sn_executor_address, - sequencer: None, - } - } - - /// Retrieves a reference to the sequencer. - #[allow(dead_code)] - pub fn sequencer_ref(&self) -> &Arc> { - // The expect is used here as it must always be set by Katana core. - // If not set, the merge on Katana may be revised. - self.sequencer - .as_ref() - .expect("Sequencer must be set to get a reference to it") - } - - /// Adds a `L1HandlerTransaction` to the transaction pool that is directed to the - /// orderbook only. - /// `L1HandlerTransaction` is a special type of transaction that can only be - /// sent by the sequencer itself. This transaction is not validated by any account. - /// - /// In the case of Solis, `L1HandlerTransaction` are sent by Solis for two purposes: - /// 1. A message was collected from the L2, and it must be executed. - /// 2. A transaction has been rejected by Solis (asset faults), and the order - /// must then be updated. - /// - /// This function is used for the scenario 2. For this reason, the `from_address` - /// field is automatically filled up by the sequencer to use the executor address - /// deployed on L2 to avoid any attack by other contracts. - /// - /// # Arguments - /// - /// * `selector` - The selector of the recipient contract to execute. - /// * `payload` - The payload of the message. - #[allow(dead_code)] - pub fn add_l1_handler_transaction_for_orderbook( - &self, - selector: FieldElement, - payload: &[FieldElement], - ) { - let to_address = self.orderbook_address; - let from_address = self.sn_executor_address; - let chain_id = ChainId::Id(CHAIN_ID_SOLIS); - - // The nonce is normally used by the messaging contract on Starknet. But in the - // case of those transaction, as they are only sent by Solis itself, we use 0. - // TODO: this value of 0 must be checked by the `l1_handler` function. - let nonce = FieldElement::ZERO; - - // The calldata always starts with the from_address. - let mut calldata: Vec = vec![from_address]; - for p in payload.into_iter() { - calldata.push(*p); - } - - let message_hash = compute_l1_message_hash(from_address, to_address, payload); - - let tx = L1HandlerTx { - nonce, - chain_id, - paid_fee_on_l1: 30000_u128, - version: FieldElement::ZERO, - message_hash, - calldata, - contract_address: ContractAddress(to_address), - entry_point_selector: selector, - }; - - if let Some(seq) = &self.sequencer { - let exe = ExecutableTxWithHash::new_query(ExecutableTx::L1Handler(tx), false); - seq.add_transaction_to_pool(exe); - } - } -} - -/// Solis hooker relies on verifiers to inspect and verify -/// the transaction and starknet state before acceptance. -#[async_trait] -impl KatanaHooker - for SolisHooker -{ - fn set_sequencer(&mut self, sequencer: Arc>) { - self.sequencer = Some(sequencer); - } - - fn set_addresses(&mut self, addresses: HookerAddresses) { - info!("HOOKER: Addresses set for hooker: {:?}", addresses); - self.orderbook_address = addresses.orderbook_arkchain; - self.sn_executor_address = addresses.executor_starknet; - - let path = Path::new(FILE_PATH_ADDRESSES); - let file = OpenOptions::new().write(true).create(true).open(&path); - - match file { - Ok(mut file) => { - let data = json!({ - "orderbook_address": format!("{:#x}", self.orderbook_address), - "sn_executor_address": format!("{:#x}", self.sn_executor_address) - }); - - if let Err(e) = writeln!(file, "{}", data.to_string()) { - eprintln!("Error writing file : {}", e); - } - } - Err(e) => { - eprintln!("Error opening file : {}", e); - } - } - } - - /// Verifies if the message is directed to the orderbook and comes from - /// the executor contract on L2. - /// - /// Currently, only the `from` and `to` are checked. - /// More checks may be added on the selector, and the data. - async fn verify_message_to_appchain( - &self, - from: FieldElement, - to: FieldElement, - _selector: FieldElement, - ) -> bool { - info!( - "HOOKER: verify_message_to_appchain called with from: {:?}, to: {:?}, {:?}, {:?}", - from, to, self.sn_executor_address, self.orderbook_address - ); - // For now, only the from/to are checked. - from == self.sn_executor_address && to == self.orderbook_address - } - - /// Verifies an invoke transaction that is: - /// 1. Directed to the orderbook only. - /// 2. With the selector `create_order` only as the fulfill - /// is verified by `verify_message_to_starknet_before_tx`. - async fn verify_invoke_tx_before_pool( - &self, - transaction: BroadcastedInvokeTransaction, - ) -> bool { - info!( - "HOOKER: verify_invoke_tx_before_pool called with transaction: {:?}", - transaction - ); - - let calldata = match transaction { - BroadcastedInvokeTransaction::V1(v1_transaction) => v1_transaction.calldata, - BroadcastedInvokeTransaction::V3(v3_transaction) => v3_transaction.calldata, - }; - info!( - "HOOKER: cairo_deserialize called with transaction: {:?}", - calldata - ); - - let calls = match Vec::::cairo_deserialize(&calldata, 0) { - Ok(calls) => calls, - Err(e) => { - tracing::error!("Fail deserializing OrderV1: {:?}", e); - return false; - } - }; - - for call in calls { - if call.selector != selector!("create_order") - && call.selector != selector!("create_order_from_l2") - && call.selector != selector!("fulfill_order_from_l2") - { - continue; - } - - if !self.verify_call(&call).await { - return false; - } - - // TODO: check assets on starknet. - // TODO: if not valid, in some cases we want to send L1HandlerTransaction - // to change the status of the order. (entrypoint to be written). - } - true - } - - async fn verify_tx_for_starknet(&self, call: Call) -> bool { - println!("verify message to starknet before tx: {:?}", call); - if call.selector != selector!("fulfill_order") { - return true; - } - - let execution_info = match ExecutionInfo::cairo_deserialize(&call.calldata, 0) { - Ok(execution_info) => execution_info, - Err(e) => { - tracing::error!("Fail deserializing ExecutionInfo: {:?}", e); - return false; - } - }; - - let verifier = OwnershipVerifier { - token_address: ContractAddress(execution_info.nft_address.into()), - token_id: execution_info.nft_token_id, - current_owner: cainome::cairo_serde::ContractAddress(execution_info.nft_from.into()), - }; - - let owner_ship_verification = self.verify_ownership(&verifier).await; - if !owner_ship_verification { - // rollback the status - let status = CancelStatus::CancelledOwnership; - - self.add_l1_handler_transaction_for_orderbook( - selector!("rollback_status_order"), - &[execution_info.order_hash, status.to_u32().into()], - ); - return false; - } - - if !self - .verify_balance(&BalanceVerifier { - currency_address: ContractAddress(execution_info.payment_currency_address.into()), - offerer: cainome::cairo_serde::ContractAddress(execution_info.nft_to.into()), - start_amount: U256 { - low: execution_info.payment_amount.low, - high: execution_info.payment_amount.high, - }, - }) - .await - { - // rollback the status - let status = CancelStatus::CancelledAssetFault; - - self.add_l1_handler_transaction_for_orderbook( - selector!("rollback_status_order"), - &[execution_info.order_hash, status.to_u32().into()], - ); - return false; - } - - true - } - - async fn on_starknet_tx_failed(&self, call: Call) { - println!("Starknet tx failed: {:?}", call); - - let execution_info = match ExecutionInfo::cairo_deserialize(&call.calldata, 0) { - Ok(execution_info) => execution_info, - Err(e) => { - tracing::error!("Fail deserializing ExecutionInfo: {:?}", e); - return; - } - }; - - // rollback the status - self.add_l1_handler_transaction_for_orderbook( - selector!("rollback_status_order"), - &[execution_info.order_hash], - ); - } -} - -#[cfg(test)] -mod test { - use super::*; - use starknet::macros::{felt, selector}; - - #[test] - fn test_calldata_calls_parsing_new_encoding() { - // Calldata for a transaction to starkgate: - // Tx hash Goerli: 0x78140a4777bdf508feec62485c2d49b90b8346875c19470790935bcfbb9594 - let data = vec![ - FieldElement::ONE, - // to (starkgate). - felt!("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"), - // selector (transfert). - felt!("0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e"), - // data offset. - felt!("0x0"), - // data len. - felt!("0x0"), - // Calldata len. - FieldElement::THREE, - felt!("0x06cdcce7333a7143ad0aebbaffe54a809cc53b65c0936ecfbebaecc0de099e8e"), - felt!("0x071afd498d0000"), - felt!("0x00"), - ]; - - let calls = match Vec::::cairo_deserialize(&data, 0) { - Ok(calls) => calls, - Err(e) => { - tracing::error!("Fail deserializing OrderV1: {:?}", e); - Vec::new() - } - }; - - assert_eq!(calls.len(), 1); - assert_eq!( - calls[0].to, - felt!("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").into() - ); - assert_eq!(calls[0].selector, selector!("transfer")); - } -} diff --git a/crates/solis/src/main.rs b/crates/solis/src/main.rs deleted file mode 100644 index becfedaa9..000000000 --- a/crates/solis/src/main.rs +++ /dev/null @@ -1,281 +0,0 @@ -use std::io; -use std::net::SocketAddr; -use std::sync::Arc; - -use crate::hooker::SolisHooker; -use clap::{CommandFactory, Parser}; -use clap_complete::{generate, Shell}; -use console::Style; -use dojo_metrics::{metrics_process, prometheus_exporter}; -use katana_core::constants::MAX_RECURSION_DEPTH; -use katana_core::env::get_default_vm_resource_fee_cost; -use katana_core::hooker::KatanaHooker; -use katana_core::sequencer::KatanaSequencer; -use katana_executor::SimulationFlag; -use katana_primitives::class::ClassHash; -use katana_primitives::contract::ContractAddress; -use katana_primitives::env::{CfgEnv, FeeTokenAddressses}; -use katana_primitives::genesis::allocation::GenesisAccountAlloc; -use katana_primitives::genesis::Genesis; -use katana_rpc::{spawn, NodeHandle}; -use starknet::core::types::FieldElement; -use tokio::signal::ctrl_c; -use tokio::sync::RwLock as AsyncRwLock; -use tracing::info; - -mod args; -mod contracts; -mod hooker; -mod utils; - -// Chain ID: 'SOLIS' cairo short string. -pub const CHAIN_ID_SOLIS: FieldElement = FieldElement::from_mont([ - 18446732623703627169, - 18446744073709551615, - 18446744073709551615, - 576266102202707888, -]); - -use args::Commands::Completions; -use args::KatanaArgs; - -pub(crate) const LOG_TARGET: &str = "katana::cli"; - -#[tokio::main] -async fn main() -> Result<(), Box> { - dotenv::dotenv().ok(); - let args = KatanaArgs::parse(); - args.init_logging()?; - - if let Some(command) = args.command { - match command { - Completions { shell } => { - print_completion(shell); - return Ok(()); - } - } - } - - let server_config = args.server_config(); - let sequencer_config = args.sequencer_config(); - let starknet_config = args.starknet_config(); - - let cfg_env = CfgEnv { - chain_id: starknet_config.env.chain_id, - vm_resource_fee_cost: get_default_vm_resource_fee_cost(), - invoke_tx_max_n_steps: starknet_config.env.invoke_max_steps, - validate_max_n_steps: starknet_config.env.validate_max_steps, - max_recursion_depth: MAX_RECURSION_DEPTH, - fee_token_addresses: FeeTokenAddressses { - eth: starknet_config.genesis.fee_token.address, - strk: Default::default(), - }, - }; - - let simulation_flags = SimulationFlag { - skip_validate: starknet_config.disable_validate, - skip_fee_transfer: starknet_config.disable_fee, - ..Default::default() - }; - - // TODO: Uncomment this once we enable the 'sir' feature again because it's not compatible with - // our current Cairo version (2.6.3). cfg_if::cfg_if! { - // if #[cfg(all(feature = "blockifier", feature = "sir"))] { - // compile_error!("Cannot enable both `blockifier` and `sir` features at the same - // time"); } else if #[cfg(feature = "blockifier")] { - // use katana_executor::implementation::blockifier::BlockifierFactory; - // let executor_factory = BlockifierFactory::new(cfg_env, simulation_flags); - // } else if #[cfg(feature = "sir")] { - // use katana_executor::implementation::sir::NativeExecutorFactory; - // let executor_factory = NativeExecutorFactory::new(cfg_env, simulation_flags); - // } else { - // compile_error!("At least one of the following features must be enabled: blockifier, - // sir"); } - // } - - use katana_executor::implementation::blockifier::BlockifierFactory; - let executor_factory = BlockifierFactory::new(cfg_env, simulation_flags); - - if let Some(listen_addr) = args.metrics { - let prometheus_handle = prometheus_exporter::install_recorder("katana")?; - - info!(target: LOG_TARGET, addr = %listen_addr, "Starting metrics endpoint."); - prometheus_exporter::serve( - listen_addr, - prometheus_handle, - metrics_process::Collector::default(), - ) - .await?; - } - - // ** SOLIS - let sn_utils_reader = contracts::starknet_utils::new_starknet_utils_reader( - FieldElement::ZERO, - &sequencer_config.messaging.clone().unwrap().rpc_url, - ); - - let executor_address = FieldElement::ZERO; - let orderbook_address = FieldElement::ZERO; - - let hooker = Arc::new(AsyncRwLock::new(SolisHooker::new( - sn_utils_reader, - orderbook_address, - executor_address, - ))); - // ** - - let sequencer = Arc::new( - KatanaSequencer::new( - executor_factory, - sequencer_config, - starknet_config, - Some(hooker.clone()), - ) - .await?, - ); - let NodeHandle { addr, handle, .. } = spawn(Arc::clone(&sequencer), server_config).await?; - - // ** SOLIS - // Important to set the sequencer reference in the hooker, to allow the hooker - // to send `L1HandlerTransaction` to the orderbook. - hooker.write().await.set_sequencer(sequencer.clone()); - // ** - - if !args.silent { - let genesis = &sequencer.backend().config.genesis; - print_intro(&args, genesis, addr); - } - - // Wait until Ctrl + C is pressed, then shutdown - ctrl_c().await?; - handle.stop()?; - - Ok(()) -} - -fn print_completion(shell: Shell) { - let mut command = KatanaArgs::command(); - let name = command.get_name().to_string(); - generate(shell, &mut command, name, &mut io::stdout()); -} - -fn print_intro(args: &KatanaArgs, genesis: &Genesis, address: SocketAddr) { - let mut accounts = genesis.accounts().peekable(); - let account_class_hash = accounts.peek().map(|e| e.1.class_hash()); - let seed = &args.starknet.seed; - - if args.json_log { - info!( - target: LOG_TARGET, - "{}", - serde_json::json!({ - "accounts": accounts.map(|a| serde_json::json!(a)).collect::>(), - "seed": format!("{}", seed), - "address": format!("{address}"), - }) - ) - } else { - println!( - "{}", - Style::new().blue().apply_to( - r" - -░█████╗░██████╗░██╗░░██╗██████╗░██████╗░░█████╗░░░░░░██╗███████╗░█████╗░████████╗ -██╔══██╗██╔══██╗██║░██╔╝██╔══██╗██╔══██╗██╔══██╗░░░░░██║██╔════╝██╔══██╗╚══██╔══╝ -███████║██████╔╝█████═╝░██████╔╝██████╔╝██║░░██║░░░░░██║█████╗░░██║░░╚═╝░░░██║░░░ -██╔══██║██╔══██╗██╔═██╗░██╔═══╝░██╔══██╗██║░░██║██╗░░██║██╔══╝░░██║░░██╗░░░██║░░░ -██║░░██║██║░░██║██║░╚██╗██║░░░░░██║░░██║╚█████╔╝╚█████╔╝███████╗╚█████╔╝░░░██║░░░ -╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░░░░╚═╝░░╚═╝░╚════╝░░╚════╝░╚══════╝░╚════╝░░░░╚═╝░░░ - -░██████╗░█████╗░██╗░░░░░██╗░██████╗ -██╔════╝██╔══██╗██║░░░░░██║██╔════╝ -╚█████╗░██║░░██║██║░░░░░██║╚█████╗░ -░╚═══██╗██║░░██║██║░░░░░██║░╚═══██╗ -██████╔╝╚█████╔╝███████╗██║██████╔╝ -╚═════╝░░╚════╝░╚══════╝╚═╝╚═════╝░ -" - ) - ); - - print_genesis_contracts(genesis, account_class_hash); - print_genesis_accounts(accounts); - - println!( - r" - -ACCOUNTS SEED -============= -{seed} - " - ); - - let addr = format!( - "🚀 JSON-RPC server started: {}", - Style::new().red().apply_to(format!("http://{address}")) - ); - - println!("\n{addr}\n\n",); - } -} - -fn print_genesis_contracts(genesis: &Genesis, account_class_hash: Option) { - println!( - r" -PREDEPLOYED CONTRACTS -================== - -| Contract | Fee Token -| Address | {} -| Class Hash | {:#064x}", - genesis.fee_token.address, genesis.fee_token.class_hash, - ); - - if let Some(ref udc) = genesis.universal_deployer { - println!( - r" -| Contract | Universal Deployer -| Address | {} -| Class Hash | {:#064x}", - udc.address, udc.class_hash - ) - } - - if let Some(hash) = account_class_hash { - println!( - r" -| Contract | Account Contract -| Class Hash | {hash:#064x}" - ) - } -} - -fn print_genesis_accounts<'a, Accounts>(accounts: Accounts) -where - Accounts: Iterator, -{ - println!( - r" - -PREFUNDED ACCOUNTS -==================" - ); - - for (addr, account) in accounts { - if let Some(pk) = account.private_key() { - println!( - r" -| Account address | {addr} -| Private key | {pk:#x} -| Public key | {:#x}", - account.public_key() - ) - } else { - println!( - r" -| Account address | {addr} -| Public key | {:#x}", - account.public_key() - ) - } - } -} diff --git a/crates/solis/src/utils.rs b/crates/solis/src/utils.rs deleted file mode 100644 index db8f23505..000000000 --- a/crates/solis/src/utils.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::path::PathBuf; - -use katana_primitives::genesis::json::GenesisJson; -use katana_primitives::genesis::Genesis; - -pub fn parse_seed(seed: &str) -> [u8; 32] { - let seed = seed.as_bytes(); - - if seed.len() >= 32 { - unsafe { *(seed[..32].as_ptr() as *const [u8; 32]) } - } else { - let mut actual_seed = [0u8; 32]; - seed.iter() - .enumerate() - .for_each(|(i, b)| actual_seed[i] = *b); - actual_seed - } -} - -/// Used as clap value parser for [Genesis]. -pub fn parse_genesis(value: &str) -> Result { - let path = PathBuf::from(shellexpand::full(value)?.into_owned()); - let genesis = Genesis::try_from(GenesisJson::load(path)?)?; - Ok(genesis) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parse_genesis_file() { - let path = "./tests/test-data/genesis.json"; - parse_genesis(path).unwrap(); - } -} diff --git a/crates/solis/tests/test-data/genesis.json b/crates/solis/tests/test-data/genesis.json deleted file mode 100644 index 51436f483..000000000 --- a/crates/solis/tests/test-data/genesis.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "number": 0, - "parentHash": "0x999", - "timestamp": 5123512314, - "stateRoot": "0x99", - "sequencerAddress": "0x100", - "gasPrices": { - "ETH": 1111, - "STRK": 2222 - }, - "feeToken": { - "address": "0x55", - "name": "ETHER", - "symbol": "ETH", - "decimals": 18, - "storage": { - "0x111": "0x1", - "0x222": "0x2" - } - }, - "universalDeployer": { - "address": "0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", - "storage": { - "0x10": "0x100" - } - }, - "accounts": { - "0x66efb28ac62686966ae85095ff3a772e014e7fbf56d4c5f6fac5606d4dde23a": { - "publicKey": "0x1", - "balance": "0xD3C21BCECCEDA1000000", - "nonce": "0x1", - "storage": { - "0x1": "0x1", - "0x2": "0x2" - } - } - }, - "contracts": { - }, - "classes": [ - ] -} diff --git a/examples/core/.env.example b/examples/core/.env.example index de3c5a516..14e3b4bf5 100644 --- a/examples/core/.env.example +++ b/examples/core/.env.example @@ -1,27 +1,23 @@ -# Starknet RPC URL -STARKNET_RPC_URL=http://0.0.0.0:5050 -# Solis RPC URL -ARKCHAIN_RPC_URL=http://0.0.0.0:7777 - -# Starknet accounts -STARKNET_ACCOUNT1_ADDRESS=0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca -STARKNET_ACCOUNT1_PRIVATE_KEY=0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a -STARKNET_ACCOUNT1_PUBLIC_KEY=0x4c339f18b9d1b95b64a6d378abd1480b2e0d5d5bd33cd0828cbce4d65c27284 - -STARKNET_ACCOUNT2_ADDRESS=0xe29882a1fcba1e7e10cad46212257fea5c752a4f9b1b1ec683c503a2cf5c8a -STARKNET_ACCOUNT2_PRIVATE_KEY=0x14d6672dcb4b77ca36a887e9a11cd9d637d5012468175829e9c6e770c61642 -STARKNET_ACCOUNT2_PUBLIC_KEY=0x4c0f884b8e5b4f00d97a3aad26b2e5de0c0c76a555060c837da2e287403c01d - -SOLIS_ADMIN_ADDRESS_DEV=0x6b86e40118f29ebe393a75469b4d926c7a44c2e2681b6d319520b7c1156d114 -SOLIS_ADMIN_PRIVATE_KEY_DEV=0x1c9053c053edf324aec366a34c6901b1095b07af69495bffec7d7fe21effb1b -SOLIS_ADMIN_PUBLIC_KEY_DEV=0x2b191c2f3ecf685a91af7cf72a43e7b90e2e41220175de5c4f7498981b10053 - -SOLIS_ADMIN_ADDRESS=0x6b86e40118f29ebe393a75469b4d926c7a44c2e2681b6d319520b7c1156d114 -SOLIS_ADMIN_PRIVATE_KEY=0x1c9053c053edf324aec366a34c6901b1095b07af69495bffec7d7fe21effb1b - -# Starknet network -STARKNET_NETWORK_ID=dev -# Solis network -SOLIS_NETWORK_ID=dev - -BROKER_ID=0x6b86e40118f29ebe393a75469b4d926c7a44c2e2681b6d319520b7c1156d114 +STARKNET_RPC_URL= +STARKNET_NETWORK_ID= +SOLIS_NETWORK_ID= +BROKER_ID= +STARKNET_ACCOUNT1_ADDRESS= +STARKNET_ACCOUNT1_PRIVATE_KEY= +STARKNET_ACCOUNT2_ADDRESS= +STARKNET_ACCOUNT2_PRIVATE_KEY= +STARKNET_LISTING_BROKER_ACCOUNT_ADDRESS= +STARKNET_LISTING_BROKER_ACCOUNT_PRIVATE_KEY= +STARKNET_SALE_BROKER_ACCOUNT_ADDRESS= +STARKNET_SALE_BROKER_ACCOUNT_PRIVATE_KEY= +STARKNET_ADMIN_ADDRESS= +STARKNET_ADMIN_PRIVATE_KEY= +STARKNET_ARK_RECEIVER_ADDRESS= +STARKNET_ARK_RECEIVER_PRIVATE_KEY= +STARKNET_ARK_COLLECTION_RECEIVER_ADDRESS= +STARKNET_ARK_COLLECTION_RECEIVER_PRIVATE_KEY= +STARKNET_ARK_COLLECTION_2981_RECEIVER_ADDRESS= +STARKNET_ARK_COLLECTION_2981_RECEIVER_PRIVATE_KEY= +NFT_CONTRACT_ADDRESS= +NFT_CONTRACT_FIXED_FEES_ADDRESS= +NFT_CONTRACT_ROYALTIES_ADDRESS= \ No newline at end of file diff --git a/examples/core/README.md b/examples/core/README.md new file mode 100644 index 000000000..0a0c3a58a --- /dev/null +++ b/examples/core/README.md @@ -0,0 +1,36 @@ +# Core Examples Scripts + +Example scripts demonstrating marketplace functionalities using the Ark Protocol. + +## Environment Setup + +Set up the required environment variables before running any scripts. + +## Available Scripts + +### Fee Management +- `setup-fees.ts`: Configure marketplace fee structure + +### Offer Management +- `fulfill-offer.ts`: Create and fulfill token-specific offers +- `fulfill-collection-offer.ts`: Create and fulfill collection-wide offers + +### Listing Operations +- `fulfill-listing-default.ts`: Process listings with default royalties +- `fulfill-listing-collection.ts`: Handle listings with collection royalties +- `fulfill-listing-2981.ts`: Execute listings using EIP-2981 royalty standard +- `cancel-listing.ts`: Create and cancel listings + +### Auction Operations +- `fulfill-auction.ts`: Create and complete auctions +- `cancel-auction.ts`: Create and cancel auctions + +## Usage + +1. Configure environment variables +2. Execute scripts: +```bash +npx bun scripts/.ts +``` + +Each script includes detailed logging for tracking execution progress and error handling. \ No newline at end of file diff --git a/examples/core/config/index.ts b/examples/core/config/index.ts index 220d3f073..0423c7159 100644 --- a/examples/core/config/index.ts +++ b/examples/core/config/index.ts @@ -17,9 +17,15 @@ interface DevContracts extends BaseContracts { eth: string; } +interface DeployedContracts extends BaseContracts { + nftContract: string; + nftContractFixedFees: string; + nftContractRoyalties: string; +} + interface DeployedContracts { - sepolia: BaseContracts; - mainnet: BaseContracts; + sepolia: DeployedContracts; + mainnet: DeployedContracts; } // Type guard to check if contracts object has NFT-related properties @@ -56,14 +62,28 @@ export const network = (process.env.STARKNET_NETWORK_ID || "dev") as Network; export const isDev = network === "dev"; // Function to get the correct contract configuration based on the network -function getContractConfig(network: Network): BaseContracts | DevContracts { +function getContractConfig(network: Network): DevContracts | DeployedContracts { switch (network) { case "dev": return typedContractsDev; case "sepolia": - return typedContractsDeployed.sepolia; + return { + ...typedContractsDeployed.sepolia, + nftContract: process.env.NFT_CONTRACT_ADDRESS as string, + nftContractFixedFees: process.env + .NFT_CONTRACT_FIXED_FEES_ADDRESS as string, + nftContractRoyalties: process.env + .NFT_CONTRACT_ROYALTIES_ADDRESS as string + }; case "mainnet": - return typedContractsDeployed.mainnet; + return { + ...typedContractsDeployed.mainnet, + nftContract: process.env.NFT_CONTRACT_ADDRESS as string, + nftContractFixedFees: process.env + .NFT_CONTRACT_FIXED_FEES_ADDRESS as string, + nftContractRoyalties: process.env + .NFT_CONTRACT_ROYALTIES_ADDRESS as string + }; default: throw new Error(`Unsupported network: ${network}`); } @@ -77,10 +97,6 @@ export const starknetExecutorContract = verifyContractAddress( contracts.executor, "Executor" ); -export const arkchainOrderbookContract = verifyContractAddress( - contracts.orderbook, - "Orderbook" -); export const starknetCurrencyContract = verifyContractAddress( isDev && isDevContracts(contracts) ? contracts.eth : starknetEthContract, "Currency" @@ -100,7 +116,5 @@ export const nftContractRoyalties = isDevContracts(contracts) export const config = createConfig({ starknetNetwork: network, starknetExecutorContract, - starknetCurrencyContract, - arkchainNetwork: network, - arkchainOrderbookContract + starknetCurrencyContract }); diff --git a/examples/core/createBroker.ts b/examples/core/createBroker.ts deleted file mode 100644 index 06624bcb2..000000000 --- a/examples/core/createBroker.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createBroker } from "@ark-project/core"; - -import { config } from "./config/index.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; - -const accounts = await setupAccounts(config); -await createBroker(config, { - brokenAccount: accounts.broker_listing, - numerator: 1, - denominator: 100 -}); diff --git a/examples/core/fulfillAuction.ts b/examples/core/fulfillAuction.ts deleted file mode 100644 index af0bc76b0..000000000 --- a/examples/core/fulfillAuction.ts +++ /dev/null @@ -1,121 +0,0 @@ -import "dotenv/config"; - -import * as sn from "starknet"; - -import { - AuctionV1, - Config, - createAuction, - createBroker, - createOffer, - fulfillAuction, - FulfillAuctionInfo, - getOrderStatus, - OfferV1 -} from "@ark-project/core"; - -import { config, nftContract } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; - -async function createAndFulfillAuction( - config: Config, - accounts: Accounts, - tokenId: bigint -): Promise { - const brokerId = accounts.broker_listing.address; - - // Create auction - const auction: AuctionV1 = { - brokerId, - tokenAddress: nftContract as string, - tokenId, - startAmount: BigInt(1), - endAmount: BigInt(10) - }; - - logger.info("Creating auction..."); - const auctionOrderHash = await createAuction(config, { - starknetAccount: accounts.fulfiller, - order: auction, - approveInfo: { - tokenAddress: nftContract as string, - tokenId - } - }); - - await new Promise((resolve) => setTimeout(resolve, 5000)); - - // Create offer - const offer: OfferV1 = { - brokerId, - tokenAddress: nftContract as string, - tokenId, - startAmount: BigInt(1) - }; - - logger.info("Creating offer..."); - const offerOrderHash = await createOffer(config, { - starknetAccount: accounts.offerer, - offer, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: offer.startAmount - } - }); - - await new Promise((resolve) => setTimeout(resolve, 5000)); - - // Fulfill auction - const fulfillAuctionInfo: FulfillAuctionInfo = { - orderHash: auctionOrderHash, - relatedOrderHash: offerOrderHash, - tokenAddress: auction.tokenAddress, - tokenId, - brokerId - }; - - logger.info("Fulfilling auction..."); - await fulfillAuction(config, { - starknetAccount: accounts.fulfiller, - fulfillAuctionInfo - }); - - await new Promise((resolve) => setTimeout(resolve, 5000)); - - const { orderStatus } = await getOrderStatus(config, { - orderHash: auctionOrderHash - }); - logger.info("Auction order status:", orderStatus); -} - -async function main(): Promise { - logger.info( - "Starting the auction creation, offer, and fulfillment process..." - ); - - const accounts = await setupAccounts(config); - - await createBroker(config, { - brokenAccount: accounts.broker_listing, - numerator: 1, - denominator: 100 - }); - - logger.info("Minting tokens..."); - const { tokenId } = await mintTokens( - config, - accounts, - nftContract as string, - true - ); - - await createAndFulfillAuction(config, accounts, tokenId); -} - -main().catch((error) => { - logger.error("An error occurred:", error); - process.exit(1); -}); diff --git a/examples/core/getOrder.ts b/examples/core/getOrder.ts deleted file mode 100644 index eda6d74aa..000000000 --- a/examples/core/getOrder.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getOrder } from "@ark-project/core"; - -import { config } from "./config/index.js"; - -(async () => { - console.log("=> Getting order..."); - const order = await getOrder(config, { - orderHash: - BigInt(0x04ee020dfcb4c4abf7355c4058f5210f8aa73ac98e579ddac5d414295c858455) - }); - - console.log("=> Order: ", order); -})(); diff --git a/examples/core/getOrderHash.ts b/examples/core/getOrderHash.ts deleted file mode 100644 index 63959ba7b..000000000 --- a/examples/core/getOrderHash.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { getOrderHash } from "@ark-project/core"; - -import { config } from "./config/index.js"; - -(async () => { - console.log("=> Getting order hash"); - - const order = await getOrderHash(config, { - tokenId: BigInt(44), - tokenAddress: - "0x032d99485b22f2e58c8a0206d3b3bb259997ff0db70cffd25585d7dd9a5b0546" - }); - - console.log("=> Order: ", order); -})(); diff --git a/examples/core/package.json b/examples/core/package.json index fa53daf59..9116a2b5e 100644 --- a/examples/core/package.json +++ b/examples/core/package.json @@ -3,6 +3,7 @@ "module": "index.ts", "type": "module", "version": "0.0.6", + "private": true, "scripts": { "run:example": "bun run", "typecheck": "tsc --noEmit" diff --git a/examples/core/cancelAuction.ts b/examples/core/scripts/cancelAuction.ts similarity index 71% rename from examples/core/cancelAuction.ts rename to examples/core/scripts/cancelAuction.ts index 687e87737..5dcf0c40e 100644 --- a/examples/core/cancelAuction.ts +++ b/examples/core/scripts/cancelAuction.ts @@ -9,11 +9,11 @@ import { getOrderStatus } from "@ark-project/core"; -import { config, nftContract } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; +import { config, nftContract } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createAndCancelAuctionAndCheckStatus( config: Config, @@ -22,13 +22,11 @@ async function createAndCancelAuctionAndCheckStatus( auction: AuctionV1 ): Promise { logger.info("Creating auction..."); - const orderHash = await createAuction(config, { - starknetAccount: accounts.fulfiller, - order: auction, - approveInfo: { - tokenAddress: nftContract, - tokenId - } + const { orderHash } = await createAuction(config, { + account: accounts.fulfiller, + ...auction, + tokenAddress: nftContract, + tokenId }); logger.info("Cancelling auction..."); @@ -39,12 +37,10 @@ async function createAndCancelAuctionAndCheckStatus( }; await cancelOrder(config, { - starknetAccount: accounts.fulfiller, - cancelInfo + account: accounts.fulfiller, + ...cancelInfo }); - await new Promise((resolve) => setTimeout(resolve, 5000)); - logger.info("Fetching order status..."); const { orderStatus } = await getOrderStatus(config, { orderHash }); logger.info("Auction order status after cancellation:", orderStatus); @@ -70,7 +66,7 @@ async function main(): Promise { ); const auction: AuctionV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: nftContract, tokenId, startAmount: BigInt(orderAmount), diff --git a/examples/core/cancelListing.ts b/examples/core/scripts/cancelListing.ts similarity index 69% rename from examples/core/cancelListing.ts rename to examples/core/scripts/cancelListing.ts index 0773fc3b2..07356fd94 100644 --- a/examples/core/cancelListing.ts +++ b/examples/core/scripts/cancelListing.ts @@ -9,11 +9,11 @@ import { ListingV1 } from "@ark-project/core"; -import { config, nftContract } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; +import { config, nftContract } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createAndCancelListing( config: Config, @@ -21,17 +21,13 @@ async function createAndCancelListing( order: ListingV1 ): Promise { logger.info("Creating listing..."); - const orderHash = await createListing(config, { - starknetAccount: accounts.offerer, - order, - approveInfo: { - tokenAddress: order.tokenAddress, - tokenId: order.tokenId - } + const { orderHash } = await createListing(config, { + account: accounts.offerer, + ...order, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId }); - await new Promise((resolve) => setTimeout(resolve, 5000)); - logger.info("Fetching order status after creation..."); const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { orderHash @@ -46,12 +42,10 @@ async function createAndCancelListing( }; await cancelOrder(config, { - starknetAccount: accounts.offerer, - cancelInfo + account: accounts.offerer, + ...cancelInfo }); - await new Promise((resolve) => setTimeout(resolve, 5000)); - logger.info("Fetching order status after cancellation..."); const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { orderHash @@ -78,10 +72,10 @@ async function main(): Promise { ); const order: ListingV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: nftContract, tokenId: tokenId, - startAmount: BigInt(orderAmount) + amount: BigInt(orderAmount) }; await createAndCancelListing(config, accounts, order); diff --git a/examples/core/createAuction.ts b/examples/core/scripts/createAuction.ts similarity index 71% rename from examples/core/createAuction.ts rename to examples/core/scripts/createAuction.ts index 788c2545f..8270bcc71 100644 --- a/examples/core/createAuction.ts +++ b/examples/core/scripts/createAuction.ts @@ -8,11 +8,11 @@ import { getOrderStatus } from "@ark-project/core"; -import { config, nftContract } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; +import { config, nftContract } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createAuctionAndCheckStatus( config: Config, @@ -21,13 +21,11 @@ async function createAuctionAndCheckStatus( auction: AuctionV1 ): Promise { logger.info("Creating auction..."); - const orderHash = await createAuction(config, { - starknetAccount: accounts.fulfiller, - order: auction, - approveInfo: { - tokenAddress: nftContract, - tokenId - } + const { orderHash } = await createAuction(config, { + account: accounts.fulfiller, + ...auction, + tokenAddress: nftContract, + tokenId }); logger.info("Fetching order status..."); @@ -48,7 +46,6 @@ async function main(): Promise { denominator: 100 }); - logger.info("Minting tokens..."); const { tokenId, orderAmount } = await mintTokens( config, accounts, @@ -57,7 +54,7 @@ async function main(): Promise { ); const auction: AuctionV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: nftContract, tokenId, startAmount: BigInt(orderAmount), diff --git a/examples/core/scripts/createBroker.ts b/examples/core/scripts/createBroker.ts new file mode 100644 index 000000000..829882c53 --- /dev/null +++ b/examples/core/scripts/createBroker.ts @@ -0,0 +1,13 @@ +import { createBroker } from "@ark-project/core"; + +import { config } from "../config/index.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; + +const accounts = await setupAccounts(config); +const transactionHash = await createBroker(config, { + brokenAccount: accounts.broker_listing, + numerator: 1, + denominator: 100 +}); +console.log("Broker created successfully"); +console.log("Order hash:", transactionHash); diff --git a/examples/core/createListing.ts b/examples/core/scripts/createListing.ts similarity index 67% rename from examples/core/createListing.ts rename to examples/core/scripts/createListing.ts index 976166666..a2fdcdd50 100644 --- a/examples/core/createListing.ts +++ b/examples/core/scripts/createListing.ts @@ -8,12 +8,12 @@ import { ListingV1 } from "@ark-project/core"; -import { config, nftContract } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { getTokenOwner } from "./utils/getTokenOwner.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; +import { config, nftContract } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { getTokenOwner } from "../utils/getTokenOwner.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createListingAndCheckStatus( config: Config, @@ -21,18 +21,14 @@ async function createListingAndCheckStatus( order: ListingV1 ): Promise { logger.info("Creating listing..."); - const orderHash = await createListing(config, { - starknetAccount: accounts.offerer, - order, - approveInfo: { - tokenAddress: order.tokenAddress, - tokenId: order.tokenId - } + const { orderHash } = await createListing(config, { + account: accounts.offerer, + ...order, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId }); logger.info("Order hash:", orderHash); - await new Promise((resolve) => setTimeout(resolve, 2000)); - logger.info("Fetching order status..."); const { orderStatus } = await getOrderStatus(config, { orderHash }); logger.info("Order status:", orderStatus); @@ -62,10 +58,10 @@ async function main(): Promise { logger.info(`Owner of tokenId ${tokenId} is ${ownerHex}`); const order: ListingV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: nftContract, tokenId: tokenId, - startAmount: BigInt(orderAmount) + amount: BigInt(orderAmount) }; await createListingAndCheckStatus(config, accounts, order); diff --git a/examples/core/createOffer.ts b/examples/core/scripts/createOffer.ts similarity index 54% rename from examples/core/createOffer.ts rename to examples/core/scripts/createOffer.ts index b18776d25..e7baa5e3f 100644 --- a/examples/core/createOffer.ts +++ b/examples/core/scripts/createOffer.ts @@ -1,21 +1,17 @@ import "dotenv/config"; -import * as sn from "starknet"; - import { Config, - createBroker, createOffer, - fetchOrCreateAccount, getOrderStatus, OfferV1 } from "@ark-project/core"; -import { config, nftContract } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; +import { config, nftContract } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createOfferAndCheckStatus( config: Config, @@ -23,18 +19,13 @@ async function createOfferAndCheckStatus( offer: OfferV1 ): Promise { logger.info("Creating offer..."); - const orderHash = await createOffer(config, { - starknetAccount: accounts.offerer, - offer, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: offer.startAmount - } + const { orderHash } = await createOffer(config, { + account: accounts.offerer, + ...offer, + currencyAddress: config.starknetCurrencyContract, + amount: offer.amount }); logger.info("Order hash:", orderHash); - - await new Promise((resolve) => setTimeout(resolve, 5000)); - logger.info("Fetching order status..."); const { orderStatus } = await getOrderStatus(config, { orderHash }); logger.info("Order status:", orderStatus); @@ -44,22 +35,18 @@ async function createOfferAndCheckStatus( async function main(): Promise { logger.info("Starting the offer creation and status check process..."); - const accounts = await setupAccounts(config); - - logger.info("Minting tokens..."); - const { orderAmount } = await mintTokens( + const { tokenId, orderAmount } = await mintTokens( config, accounts, nftContract as string, true ); - const offer: OfferV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: nftContract as string, - tokenId: BigInt(20), // Note: This is hardcoded, you might want to generate this dynamically - startAmount: orderAmount, + tokenId: tokenId, + amount: orderAmount, currencyAddress: config.starknetCurrencyContract }; diff --git a/examples/core/scripts/fulfillAuction.ts b/examples/core/scripts/fulfillAuction.ts new file mode 100644 index 000000000..54a019d5a --- /dev/null +++ b/examples/core/scripts/fulfillAuction.ts @@ -0,0 +1,121 @@ +import "dotenv/config"; + +import { + AuctionV1, + Config, + createAuction, + createOffer, + fulfillAuction, + FulfillAuctionInfo, + getOrderStatus, + OfferV1 +} from "@ark-project/core"; + +import { config, nftContract } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { displayBalances } from "../utils/displayBalances.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; + +async function createAndFulfillAuction( + config: Config, + accounts: Accounts, + tokenId: bigint +): Promise { + const brokerAddressListing = accounts.broker_listing.address; + const brokerAddressSale = accounts.broker_sale.address; + + // Create auction + const auction: AuctionV1 = { + brokerAddress: brokerAddressListing, + tokenAddress: nftContract as string, + tokenId, + startAmount: BigInt(1000000000000000), + endAmount: BigInt(10000000000000000) + }; + + logger.info("Creating auction..."); + const { orderHash: auctionOrderHash } = await createAuction(config, { + account: accounts.fulfiller, + ...auction, + tokenAddress: nftContract as string, + tokenId + }); + + // Create offer + const offer: OfferV1 = { + brokerAddress: brokerAddressSale, + tokenAddress: nftContract as string, + tokenId, + amount: BigInt(10000000000000000) + }; + + logger.info("Creating offer..."); + const { orderHash: offerOrderHash } = await createOffer(config, { + account: accounts.offerer, + ...offer, + currencyAddress: config.starknetCurrencyContract, + amount: offer.amount + }); + + // Fulfill auction + const fulfillAuctionInfo: FulfillAuctionInfo = { + orderHash: auctionOrderHash, + relatedOrderHash: offerOrderHash, + tokenAddress: auction.tokenAddress, + tokenId, + brokerAddress: brokerAddressSale, + }; + + logger.info("Fulfilling auction..."); + const { transactionHash } = await fulfillAuction(config, { + account: accounts.fulfiller, + ...fulfillAuctionInfo, + quantity: 1n + }); + + logger.info("Auction fulfilled."); + logger.info(`https://sepolia.starkscan.co/tx/${transactionHash}`); + return auctionOrderHash; +} + +async function main(): Promise { + logger.info( + "Starting the auction creation, offer, and fulfillment process..." + ); + + const accounts = await setupAccounts(config); + + logger.info("Minting tokens..."); + const { tokenId } = await mintTokens( + config, + accounts, + nftContract as string, + true + ); + + await displayBalances( + config, + accounts, + "before collection offer creation and fulfillment" + ); + + const orderHash = await createAndFulfillAuction(config, accounts, tokenId); + + const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { + orderHash + }); + logger.info("Order status after fulfillment:", orderStatusAfter); + + await displayBalances( + config, + accounts, + "after collection offer creation and fulfillment" + ); +} + +main().catch((error) => { + logger.error("An error occurred:", error); + process.exit(1); +}); diff --git a/examples/core/fulfillCollectionOffer.ts b/examples/core/scripts/fulfillCollectionOffer.ts similarity index 55% rename from examples/core/fulfillCollectionOffer.ts rename to examples/core/scripts/fulfillCollectionOffer.ts index ba5b2cd26..13c7707cc 100644 --- a/examples/core/fulfillCollectionOffer.ts +++ b/examples/core/scripts/fulfillCollectionOffer.ts @@ -8,51 +8,41 @@ import { OfferV1 } from "@ark-project/core"; -import { config, nftContract } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { displayBalances } from "./utils/displayBalances.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; -import { setupFees } from "./utils/setupFees.js"; +import { config, nftContract } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { displayBalances } from "../utils/displayBalances.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createAndFulfillCollectionOffer( config: Config, accounts: Accounts, - offer: OfferV1 + offer: OfferV1, + tokenId: bigint ): Promise { logger.info("Creating collection offer..."); - const orderHash = await createOffer(config, { - starknetAccount: accounts.offerer, - offer, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: offer.startAmount - } + const { orderHash } = await createOffer(config, { + account: accounts.offerer, + ...offer, + currencyAddress: config.starknetCurrencyContract, + amount: offer.amount }); - if (config.starknetNetwork !== "dev") { - await new Promise((resolve) => setTimeout(resolve, 5000)); - } - logger.info("Fulfilling collection offer..."); - const fulfillOfferInfo = { + + const { transactionHash } = await fulfillOffer(config, { + account: accounts.fulfiller, orderHash: orderHash, tokenAddress: offer.tokenAddress, - tokenId: offer.tokenId, - brokerId: offer.brokerId - }; - - await fulfillOffer(config, { - starknetAccount: accounts.fulfiller, - fulfillOfferInfo, - approveInfo: { - tokenAddress: nftContract as string, - tokenId: offer.tokenId - } + tokenId: tokenId, + brokerAddress: offer.brokerAddress, + quantity: 1n }); logger.info("Collection offer created and fulfilled."); + logger.info("Order hash:", orderHash); + logger.info(`https://sepolia.starkscan.co/tx/${transactionHash}`); return orderHash; } @@ -62,7 +52,6 @@ async function main(): Promise { ); const accounts = await setupAccounts(config); - await setupFees(config, accounts); const { tokenId, orderAmount } = await mintTokens( config, @@ -72,10 +61,9 @@ async function main(): Promise { ); const offer: OfferV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: nftContract as string, - tokenId: tokenId, - startAmount: orderAmount + amount: orderAmount }; await displayBalances( @@ -87,11 +75,10 @@ async function main(): Promise { const orderHash = await createAndFulfillCollectionOffer( config, accounts, - offer + offer, + tokenId ); - await new Promise((resolve) => setTimeout(resolve, 5000)); - const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { orderHash }); diff --git a/examples/core/fulfillListing2981Royalties.ts b/examples/core/scripts/fulfillListing2981Royalties.ts similarity index 52% rename from examples/core/fulfillListing2981Royalties.ts rename to examples/core/scripts/fulfillListing2981Royalties.ts index 330d27e71..54fb4ee33 100644 --- a/examples/core/fulfillListing2981Royalties.ts +++ b/examples/core/scripts/fulfillListing2981Royalties.ts @@ -1,5 +1,7 @@ import "dotenv/config"; +import { log } from "winston"; + import { Config, createListing, @@ -8,13 +10,12 @@ import { ListingV1 } from "@ark-project/core"; -import { config, contracts, isDev } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { displayBalances } from "./utils/displayBalances.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; -import { setupFees } from "./utils/setupFees.js"; +import { config, contracts } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { displayBalances } from "../utils/displayBalances.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createAndFulfillListing( config: Config, @@ -22,47 +23,36 @@ async function createAndFulfillListing( order: ListingV1 ): Promise { logger.info("Creating listing..."); - const orderHash = await createListing(config, { - starknetAccount: accounts.offerer, - order, - approveInfo: { - tokenAddress: order.tokenAddress, - tokenId: order.tokenId - } + const { orderHash } = await createListing(config, { + account: accounts.offerer, + ...order, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId }); - await new Promise((resolve) => setTimeout(resolve, 5000)); - logger.info("Fulfilling listing..."); - const fulfillListingInfo = { + + const { transactionHash } = await fulfillListing(config, { + account: accounts.fulfiller, orderHash: orderHash, tokenAddress: order.tokenAddress, tokenId: order.tokenId, - brokerId: accounts.broker_sale.address - }; - - await fulfillListing(config, { - starknetAccount: accounts.fulfiller, - fulfillListingInfo, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: order.startAmount - } + brokerAddress: accounts.broker_sale.address, + currencyAddress: config.starknetCurrencyContract, + amount: order.amount, + quantity: 1n }); logger.info("Listing created and fulfilled."); + logger.info("Order hash:", orderHash); + logger.info(`https://sepolia.starkscan.co/tx/${transactionHash}`); return orderHash; } async function main(): Promise { - if (!isDev || !("nftContract" in contracts)) { - throw new Error("NFT contract is not available in this environment"); - } - logger.info("Starting the listing process..."); const accounts = await setupAccounts(config); - await setupFees(config, accounts); const { tokenId, orderAmount } = await mintTokens( config, @@ -71,18 +61,16 @@ async function main(): Promise { ); const order: ListingV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: contracts.nftContractRoyalties, tokenId: tokenId, - startAmount: BigInt(orderAmount) + amount: BigInt(orderAmount) }; await displayBalances(config, accounts, "before sale"); const orderHash = await createAndFulfillListing(config, accounts, order); - await new Promise((resolve) => setTimeout(resolve, 5000)); - const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { orderHash }); diff --git a/examples/core/fulfillListingCollectionRoyalties.ts b/examples/core/scripts/fulfillListingCollectionRoyalties.ts similarity index 51% rename from examples/core/fulfillListingCollectionRoyalties.ts rename to examples/core/scripts/fulfillListingCollectionRoyalties.ts index 9c13a89d7..061352291 100644 --- a/examples/core/fulfillListingCollectionRoyalties.ts +++ b/examples/core/scripts/fulfillListingCollectionRoyalties.ts @@ -1,7 +1,5 @@ import "dotenv/config"; -import { log } from "winston"; - import { Config, createListing, @@ -10,13 +8,12 @@ import { ListingV1 } from "@ark-project/core"; -import { config, contracts, isDev } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { displayBalances } from "./utils/displayBalances.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; -import { setupFees } from "./utils/setupFees.js"; +import { config, contracts, isDev } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { displayBalances } from "../utils/displayBalances.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createAndFulfillListing( config: Config, @@ -24,47 +21,36 @@ async function createAndFulfillListing( order: ListingV1 ): Promise { logger.info("Creating listing..."); - const orderHash = await createListing(config, { - starknetAccount: accounts.offerer, - order, - approveInfo: { - tokenAddress: order.tokenAddress, - tokenId: order.tokenId - } + const { orderHash } = await createListing(config, { + account: accounts.offerer, + ...order, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId }); - await new Promise((resolve) => setTimeout(resolve, 2000)); - logger.info("Fulfilling listing..."); - const fulfillListingInfo = { + + const { transactionHash } = await fulfillListing(config, { + account: accounts.fulfiller, orderHash: orderHash, tokenAddress: order.tokenAddress, tokenId: order.tokenId, - brokerId: accounts.broker_sale.address - }; - - await fulfillListing(config, { - starknetAccount: accounts.fulfiller, - fulfillListingInfo, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: order.startAmount - } + brokerAddress: accounts.broker_sale.address, + currencyAddress: config.starknetCurrencyContract, + amount: order.amount, + quantity: 1n }); logger.info("Listing created and fulfilled."); + logger.info("Order hash:", orderHash); + logger.info(`https://sepolia.starkscan.co/tx/${transactionHash}`); return orderHash; } async function main(): Promise { - if (!isDev || !("nftContract" in contracts)) { - throw new Error("NFT contract is not available in this environment"); - } - logger.info("Starting the listing process..."); const accounts = await setupAccounts(config); - await setupFees(config, accounts); const { tokenId, orderAmount } = await mintTokens( config, @@ -73,18 +59,16 @@ async function main(): Promise { ); const order: ListingV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: contracts.nftContractFixedFees, tokenId: tokenId, - startAmount: BigInt(orderAmount) + amount: BigInt(orderAmount) }; await displayBalances(config, accounts, "before sale"); const orderHash = await createAndFulfillListing(config, accounts, order); - await new Promise((resolve) => setTimeout(resolve, 2000)); - const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { orderHash }); diff --git a/examples/core/fulfillListingDefaultRoyalties.ts b/examples/core/scripts/fulfillListingDefaultRoyalties.ts similarity index 51% rename from examples/core/fulfillListingDefaultRoyalties.ts rename to examples/core/scripts/fulfillListingDefaultRoyalties.ts index bcea75fa3..2c67a8c3f 100644 --- a/examples/core/fulfillListingDefaultRoyalties.ts +++ b/examples/core/scripts/fulfillListingDefaultRoyalties.ts @@ -8,13 +8,12 @@ import { ListingV1 } from "@ark-project/core"; -import { config, contracts, isDev } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { displayBalances } from "./utils/displayBalances.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; -import { setupFees } from "./utils/setupFees.js"; +import { config, contracts } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { displayBalances } from "../utils/displayBalances.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createAndFulfillListing( config: Config, @@ -22,46 +21,36 @@ async function createAndFulfillListing( order: ListingV1 ): Promise { logger.info("Creating listing..."); - const orderHash = await createListing(config, { - starknetAccount: accounts.offerer, - order, - approveInfo: { - tokenAddress: order.tokenAddress, - tokenId: order.tokenId - } + const { orderHash } = await createListing(config, { + account: accounts.offerer, + ...order, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId }); - await new Promise((resolve) => setTimeout(resolve, 2000)); - logger.info("Fulfilling listing..."); - const fulfillListingInfo = { + + const { transactionHash } = await fulfillListing(config, { + account: accounts.fulfiller, orderHash: orderHash, tokenAddress: order.tokenAddress, tokenId: order.tokenId, - brokerId: accounts.broker_sale.address - }; - - await fulfillListing(config, { - starknetAccount: accounts.fulfiller, - fulfillListingInfo, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: order.startAmount - } + brokerAddress: accounts.broker_sale.address, + currencyAddress: config.starknetCurrencyContract, + amount: order.amount, + quantity: 1n }); logger.info("Listing created and fulfilled."); + logger.info("Order hash:", orderHash); + logger.info(`https://sepolia.starkscan.co/tx/${transactionHash}`); return orderHash; } async function main(): Promise { - if (!isDev || !("nftContract" in contracts)) { - throw new Error("NFT contract is not available in this environment"); - } logger.info("Starting the listing process..."); const accounts = await setupAccounts(config); - await setupFees(config, accounts); const { tokenId, orderAmount } = await mintTokens( config, @@ -70,18 +59,16 @@ async function main(): Promise { ); const order: ListingV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: contracts.nftContract, tokenId: tokenId, - startAmount: BigInt(orderAmount) + amount: BigInt(orderAmount) }; await displayBalances(config, accounts, "before sale"); const orderHash = await createAndFulfillListing(config, accounts, order); - await new Promise((resolve) => setTimeout(resolve, 2000)); - const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { orderHash }); diff --git a/examples/core/fulfillOffer.ts b/examples/core/scripts/fulfillOffer.ts similarity index 50% rename from examples/core/fulfillOffer.ts rename to examples/core/scripts/fulfillOffer.ts index 371e160b8..ab6625f91 100644 --- a/examples/core/fulfillOffer.ts +++ b/examples/core/scripts/fulfillOffer.ts @@ -1,7 +1,5 @@ import "dotenv/config"; -import * as sn from "starknet"; - import { Config, createOffer, @@ -10,51 +8,41 @@ import { OfferV1 } from "@ark-project/core"; -import { config, nftContract } from "./config/index.js"; -import { Accounts } from "./types/accounts.js"; -import { displayBalances } from "./utils/displayBalances.js"; -import { logger } from "./utils/logger.js"; -import { mintTokens } from "./utils/mintTokens.js"; -import { setupAccounts } from "./utils/setupAccounts.js"; -import { setupFees } from "./utils/setupFees.js"; +import { config, nftContract } from "../config/index.js"; +import { Accounts } from "../types/accounts.js"; +import { displayBalances } from "../utils/displayBalances.js"; +import { logger } from "../utils/logger.js"; +import { mintTokens } from "../utils/mintTokens.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; async function createAndFulfillOffer( config: Config, accounts: Accounts, - offer: OfferV1 + offer: OfferV1, + tokenId: bigint ): Promise { logger.info("Creating offer..."); - const orderHash = await createOffer(config, { - starknetAccount: accounts.offerer, - offer, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: offer.startAmount - } + const { orderHash } = await createOffer(config, { + account: accounts.offerer, + ...offer, + currencyAddress: config.starknetCurrencyContract, + amount: offer.amount }); - if (config.starknetNetwork !== "dev") { - await new Promise((resolve) => setTimeout(resolve, 5000)); - } - logger.info("Fulfilling offer..."); - const fulfillOfferInfo = { + + const { transactionHash } = await fulfillOffer(config, { + account: accounts.fulfiller, orderHash: orderHash, tokenAddress: offer.tokenAddress, - tokenId: offer.tokenId, - brokerId: offer.brokerId - }; - - await fulfillOffer(config, { - starknetAccount: accounts.fulfiller, - fulfillOfferInfo, - approveInfo: { - tokenAddress: nftContract as string, - tokenId: offer.tokenId - } + tokenId: tokenId, + brokerAddress: offer.brokerAddress, + quantity: 1n }); logger.info("Offer created and fulfilled."); + logger.info("Order hash:", orderHash); + logger.info(`https://sepolia.starkscan.co/tx/${transactionHash}`); return orderHash; } @@ -62,7 +50,6 @@ async function main(): Promise { logger.info("Starting the offer creation and fulfillment process..."); const accounts = await setupAccounts(config); - await setupFees(config, accounts); const { tokenId, orderAmount } = await mintTokens( config, @@ -72,10 +59,10 @@ async function main(): Promise { ); const offer: OfferV1 = { - brokerId: accounts.broker_listing.address, + brokerAddress: accounts.broker_listing.address, tokenAddress: nftContract as string, tokenId: tokenId, - startAmount: orderAmount + amount: orderAmount }; await displayBalances( @@ -84,9 +71,12 @@ async function main(): Promise { "before offer creation and fulfillment" ); - const orderHash = await createAndFulfillOffer(config, accounts, offer); - - await new Promise((resolve) => setTimeout(resolve, 5000)); + const orderHash = await createAndFulfillOffer( + config, + accounts, + offer, + tokenId + ); const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { orderHash diff --git a/examples/core/scripts/setupFees.ts b/examples/core/scripts/setupFees.ts new file mode 100644 index 000000000..e77d90d7f --- /dev/null +++ b/examples/core/scripts/setupFees.ts @@ -0,0 +1,18 @@ +import "dotenv/config"; + +import { config } from "../config/index.js"; +import { logger } from "../utils/logger.js"; +import { setupAccounts } from "../utils/setupAccounts.js"; +import { setupFees } from "../utils/setupFees.js"; + +async function main(): Promise { + logger.info("Starting the listing process..."); + + const accounts = await setupAccounts(config); + await setupFees(config, accounts); +} + +main().catch((error) => { + logger.error("An error occurred:", error); + process.exit(1); +}); diff --git a/examples/core/utils/mintTokens.ts b/examples/core/utils/mintTokens.ts index 6d7e8f68d..b82ae91cb 100644 --- a/examples/core/utils/mintTokens.ts +++ b/examples/core/utils/mintTokens.ts @@ -15,13 +15,14 @@ export async function mintTokens( logger.info("Minting tokens..."); let tokenId: bigint; - const orderAmount = BigInt(100000000000000000); + const orderAmount = BigInt(10000000000000000); if (isOffer) { // For offers, mint ERC20 for offerer and ERC721 for fulfiller - logger.info("Minting ERC20 for the offerer..."); - await mintERC20(config.starknetProvider, accounts.offerer, orderAmount); - + if (process.env.STARKNET_NETWORK_ID === "dev") { + logger.info("Minting ERC20 for the offerer..."); + await mintERC20(config.starknetProvider, accounts.offerer, orderAmount); + } logger.info("Minting ERC721 for the fulfiller..."); const transaction_hash = await mintERC721( config.starknetProvider, @@ -44,11 +45,6 @@ export async function mintTokens( } } - if (config.starknetNetwork !== "dev") { - logger.info("Waiting for 5 minutes for transaction to complete..."); - await new Promise((resolve) => setTimeout(resolve, 5 * 60 * 1000)); - } - tokenId = await getCurrentTokenId(config, nftContract); logger.info("Token minted with tokenId:", tokenId); diff --git a/examples/core/utils/setupFees.ts b/examples/core/utils/setupFees.ts index a309da6a5..dd271eec2 100644 --- a/examples/core/utils/setupFees.ts +++ b/examples/core/utils/setupFees.ts @@ -13,10 +13,6 @@ export async function setupFees( ): Promise { logger.info("Setting up fees..."); - if (!isDev || !("nftContract" in contracts)) { - throw new Error("NFT contract is not available in this environment"); - } - await setArkFees(config, accounts.admin, config.starknetExecutorContract, 25); await createBroker(config, { diff --git a/examples/core/utils/whitelistBroker.ts b/examples/core/utils/whitelistBroker.ts deleted file mode 100644 index 4134124db..000000000 --- a/examples/core/utils/whitelistBroker.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Account, CallData } from "starknet"; - -import { Config } from "@ark-project/core"; - -export const whitelistBroker = async ( - config: Config, - adminAccount: Account, - brokerId: string -) => { - const { abi: orderbookAbi } = await config.arkProvider.getClassAt( - config.arkchainOrderbookContract - ); - - if (orderbookAbi === undefined) { - throw new Error("no abi."); - } - - const whitelist_hash_calldata = CallData.compile({ - broker_id: brokerId - }); - - const result = await adminAccount.execute({ - contractAddress: config.arkchainOrderbookContract, - entrypoint: "whitelist_broker", - calldata: whitelist_hash_calldata - }); - - await config.arkProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); - - return result; -}; diff --git a/examples/core/src/version.ts b/examples/core/version.ts similarity index 100% rename from examples/core/src/version.ts rename to examples/core/version.ts diff --git a/package.json b/package.json index 3e0a23505..2b7cba7c2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "turbo", + "name": "@ark-project/root", "private": true, "packageManager": "pnpm@9.1.4", "engines": { @@ -8,7 +8,7 @@ "module": "index.ts", "type": "module", "scripts": { - "test": "dotenv -- turbo run test --filter='./packages/core'", + "test": "turbo run test --filter=@ark-project/core", "clean": "git clean -xdf node_modules", "clean:workspaces": "turbo clean", "build": "dotenv -- turbo run build", @@ -22,8 +22,6 @@ "format": "prettier --write \"**/*.{ts,tsx,md}\"", "accounts:new": "dotenv -- turbo run accounts:new", "accounts:deploy": "dotenv -- turbo run accounts:deploy", - "deploy:solis": "dotenv -- turbo run deploy:solis --log-prefix=none", - "deploy:solis:local": "dotenv -- turbo run deploy:solis:local --log-prefix=none", "deploy:starknet": "dotenv -- turbo run deploy:starknet", "deploy:starknet:local": "dotenv -- turbo run deploy:starknet:local --log-prefix=none", "deploy:starknet:tokens": "dotenv -- turbo run deploy:starknet:tokens --log-prefix=none", @@ -33,14 +31,18 @@ "@ark-project/eslint-config": "workspace:*", "@ark-project/typescript-config": "workspace:*", "@ianvs/prettier-plugin-sort-imports": "^4.1.1", - "@changesets/cli": "^2.27.1", "bun": "^1.0.26", "bun-types": "^1.0.26", "dotenv-cli": "^7.3.0", "glob": "^10.3.10", "prettier": "^3.1.0", - "prettier-plugin-sort-imports": "^1.8.1", - "turbo": "^1.13.3" + "prettier-plugin-sort-imports": "^1.8.1" + }, + "devDependencies": { + "@changesets/cli": "^2.27.9", + "patch-package": "^8.0.0", + "postinstall-postinstall": "^2.1.0", + "turbo": "^2.1.3" }, "peerDependencies": { "typescript": "^5.0.0" diff --git a/packages/core/.env.example b/packages/core/.env.example deleted file mode 100644 index ffd5e584a..000000000 --- a/packages/core/.env.example +++ /dev/null @@ -1,27 +0,0 @@ -# Starknet RPC URL -STARKNET_RPC_URL=http://0.0.0.0:5050 -# Solis RPC URL -ARKCHAIN_RPC_URL=http://0.0.0.0:7777 - -# Starknet accounts -STARKNET_ACCOUNT1_ADDRESS=0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca -STARKNET_ACCOUNT1_PRIVATE_KEY=0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a -STARKNET_ACCOUNT1_PUBLIC_KEY=0x4c339f18b9d1b95b64a6d378abd1480b2e0d5d5bd33cd0828cbce4d65c27284 - -STARKNET_ACCOUNT2_ADDRESS=0xe29882a1fcba1e7e10cad46212257fea5c752a4f9b1b1ec683c503a2cf5c8a -STARKNET_ACCOUNT2_PRIVATE_KEY=0x14d6672dcb4b77ca36a887e9a11cd9d637d5012468175829e9c6e770c61642 -STARKNET_ACCOUNT2_PUBLIC_KEY=0x4c0f884b8e5b4f00d97a3aad26b2e5de0c0c76a555060c837da2e287403c01d - -SOLIS_ADMIN_ADDRESS_DEV=0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca -SOLIS_ADMIN_PRIVATE_KEY_DEV=0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a -SOLIS_ADMIN_PUBLIC_KEY_DEV=0x640466ebd2ce505209d3e5c4494b4276ed8f1cde764d757eb48831961f7cdea - -SOLIS_ADMIN_ADDRESS=0x6b86e40118f29ebe393a75469b4d926c7a44c2e2681b6d319520b7c1156d114 -SOLIS_ADMIN_PRIVATE_KEY=0x1c9053c053edf324aec366a34c6901b1095b07af69495bffec7d7fe21effb1b - -# Starknet network -STARKNET_NETWORK_ID=dev -# Solis network -SOLIS_NETWORK_ID=dev - -BROKER_ID= diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 79bc7d965..797277b8a 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,23 @@ # @ark-project/core +## 3.0.0-beta.2 + +### Minor Changes + +- Update contract + +## 3.0.0-beta.1 + +### Patch Changes + +- 6d31848: Update contract address + +## 3.0.0-beta.0 + +### Major Changes + +- Update SDKs + ## 2.1.2 ### Patch Changes diff --git a/packages/core/jest.config.ts b/packages/core/jest.config.ts deleted file mode 100644 index 33e0d82c7..000000000 --- a/packages/core/jest.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * For a detailed explanation regarding each configuration property, visit: - * https://jestjs.io/docs/configuration - */ - -import type { Config } from "jest"; - -const config: Config = { - moduleNameMapper: { - "^(\\.{1,2}/.*)\\.js$": "$1" - }, - preset: "ts-jest/presets/default-esm", - setupFiles: ["/tests/setup.ts"] -}; - -export default config; diff --git a/packages/core/package.json b/packages/core/package.json index 2bdc92ebd..9c72e8e67 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@ark-project/core", - "version": "2.1.2", + "version": "3.0.0-beta.2", "license": "Apache-2.0", "scripts": { "build": "pnpm contracts:generate && pnpm build:esm+types", @@ -12,12 +12,15 @@ "contracts:generate": "tsx scripts/contracts-generate.ts", "contracts:check": "tsx scripts/contracts-check.ts", "dev": "nodemon --watch ../../contracts.json --exec 'npm run contracts:generate' & tsup src/index.ts --format cjs,esm --dts --watch", - "test": "jest tests -i" + "test": "vitest --no-file-parallelism" }, "type": "module", "main": "./dist/esm/index.js", "types": "./dist/types/index.d.ts", "typings": "./dist/types/index.d.ts", + "publishConfig": { + "access": "public" + }, "exports": { ".": { "types": "./dist/types/index.d.ts", @@ -26,25 +29,24 @@ }, "dependencies": { "@scure/starknet": "^0.3.0", - "starknet": "^6.9.0" + "starknet": "^6.23.1" }, "devDependencies": { "@ark-project/eslint-config": "workspace:*", + "@ark-project/test": "workspace:*", "@ark-project/typescript-config": "workspace:*", - "@types/jest": "^29.5.5", "@types/node": "^20.10.7", "dotenv": "^16.4.5", "esbuild": "^0.20.2", "eslint": "^8.48.0", "eslint-plugin-mocha": "^10.2.0", - "jest": "^29.7.0", "mocha": "^10.3.0", "nodemon": "^3.0.2", - "ts-jest": "^29.1.1", "ts-node": "^10.9.1", "tsup": "^8.0.1", "tsx": "^4.11.0", - "typescript": "^5.2.2" + "typescript": "^5.2.2", + "vitest": "^2.0.5" }, "peerDependencies": { "typescript": ">=5.0.4", diff --git a/packages/core/scripts/contracts-check.ts b/packages/core/scripts/contracts-check.ts index 64b5a9b0b..7db676296 100644 --- a/packages/core/scripts/contracts-check.ts +++ b/packages/core/scripts/contracts-check.ts @@ -3,6 +3,8 @@ import path from "path"; import { fileURLToPath } from "url"; import { promisify } from "util"; +import { ContractsCheckError } from "../src/errors/config.js"; + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -10,12 +12,14 @@ const execAsync = promisify(exec); const outputFilePath = path.resolve(__dirname, "..", "src", "contracts.ts"); +const docsPath = "/nft-contracts"; +const docsSlug = "list-all-nft-contracts"; async function run() { try { const { stderr } = await execAsync(`tsc --noEmit ${outputFilePath}`); if (stderr) { - throw new Error(stderr); + throw new ContractsCheckError(stderr, { docsPath, docsSlug }); } console.log("Contracts file is valid TypeScript."); diff --git a/packages/core/src/actions/account/account.ts b/packages/core/src/actions/account/account.ts index b0e6889f3..895fd544f 100644 --- a/packages/core/src/actions/account/account.ts +++ b/packages/core/src/actions/account/account.ts @@ -8,7 +8,9 @@ import { } from "starknet"; import { SOLIS_ACCOUNT_CLASS_HASH } from "../../constants.js"; +import { AccountDeployFailedError } from "../../errors/actions.js"; +const docsPath = "sdk-core/create-account"; /** * Creates a new account on the StarkNet testnet. * This function generates a private key, derives the corresponding public key, @@ -53,11 +55,11 @@ export const createAccount = async (provider: ProviderInterface) => { addressSalt: publicKey }); } catch (e) { - throw new Error(`Account deploy failed for ${address}`); + throw new AccountDeployFailedError(address, { docsPath }); } if (!response) { - throw new Error(`Account deploy failed for ${address}`); + throw new AccountDeployFailedError(address, { docsPath }); } const { transaction_hash, contract_address } = response; diff --git a/packages/core/src/actions/fees/getArkFees.ts b/packages/core/src/actions/fees/getArkFees.ts new file mode 100644 index 000000000..79454d75c --- /dev/null +++ b/packages/core/src/actions/fees/getArkFees.ts @@ -0,0 +1,37 @@ +import { Contract } from "starknet"; + +import { Config } from "../../createConfig.js"; + +export const ABI = [ + { + type: "struct", + name: "ark_oz::erc2981::fees::FeesRatio", + members: [ + { name: "numerator", type: "core::integer::u256" }, + { name: "denominator", type: "core::integer::u256" } + ] + }, + { + type: "function", + name: "get_ark_fees", + inputs: [], + outputs: [{ type: "ark_oz::erc2981::fees::FeesRatio" }], + state_mutability: "view" + } +] as const; + +export async function getArkFees(config: Config) { + const contract = new Contract( + ABI, + config.starknetExecutorContract, + config.starknetProvider + ).typedv2(ABI); + + const { numerator, denominator } = await contract.get_ark_fees(); + + return { + formatted: ((Number(numerator) / Number(denominator)) * 100).toFixed(2), + numerator, + denominator + }; +} diff --git a/packages/core/src/actions/fees/getBrokerFees.ts b/packages/core/src/actions/fees/getBrokerFees.ts new file mode 100644 index 000000000..479cb754b --- /dev/null +++ b/packages/core/src/actions/fees/getBrokerFees.ts @@ -0,0 +1,46 @@ +import { CallData, Contract } from "starknet"; + +import { Config } from "../../createConfig.js"; + +export const ABI = [ + { + type: "struct", + name: "ark_oz::erc2981::fees::FeesRatio", + members: [ + { name: "numerator", type: "core::integer::u256" }, + { name: "denominator", type: "core::integer::u256" } + ] + }, + { + type: "function", + name: "get_broker_fees", + inputs: [ + { + name: "broker_address", + type: "core::starknet::contract_address::ContractAddress" + } + ], + outputs: [{ type: "ark_oz::erc2981::fees::FeesRatio" }], + state_mutability: "view" + } +] as const; + +export async function getBrokerFees(config: Config, brokerAddress: string) { + const contract = new Contract( + ABI, + config.starknetExecutorContract, + config.starknetProvider + ).typedv2(ABI); + + const { numerator, denominator } = await contract.get_broker_fees( + CallData.compile({ + broker_address: brokerAddress + }) + ); + + return { + formatted: ((Number(numerator) / Number(denominator)) * 100).toFixed(2), + numerator, + denominator + }; +} diff --git a/packages/core/src/actions/fees/getCollectionCreatorFees.ts b/packages/core/src/actions/fees/getCollectionCreatorFees.ts new file mode 100644 index 000000000..8a43a0eef --- /dev/null +++ b/packages/core/src/actions/fees/getCollectionCreatorFees.ts @@ -0,0 +1,62 @@ +import { CallData, Contract } from "starknet"; +import { toHex } from "viem"; + +import { Config } from "../../createConfig.js"; + +export const ABI = [ + { + type: "struct", + name: "ark_oz::erc2981::fees::FeesRatio", + members: [ + { name: "numerator", type: "core::integer::u256" }, + { name: "denominator", type: "core::integer::u256" } + ] + }, + { + type: "function", + name: "get_collection_creator_fees", + inputs: [ + { + name: "nft_address", + type: "core::starknet::contract_address::ContractAddress" + } + ], + outputs: [ + { + type: "(core::starknet::contract_address::ContractAddress, ark_oz::erc2981::fees::FeesRatio)" + } + ], + state_mutability: "view" + } +] as const; + +export async function getCollectionCreatorFees( + config: Config, + tokenAddress: string +) { + const contract = new Contract( + ABI, + config.starknetExecutorContract, + config.starknetProvider + ).typedv2(ABI); + + const raw = await contract.get_collection_creator_fees( + CallData.compile({ + nft_address: tokenAddress + }) + ); + const creator = toHex(raw[0] as bigint); + const { numerator, denominator } = raw[1] as { + numerator: bigint; + denominator: bigint; + }; + + return { + creator, + fees: { + formatted: ((Number(numerator) / Number(denominator)) * 100).toFixed(2), + numerator, + denominator + } + }; +} diff --git a/packages/core/src/actions/fees/getDefaultCreatorFees.ts b/packages/core/src/actions/fees/getDefaultCreatorFees.ts new file mode 100644 index 000000000..00777f49b --- /dev/null +++ b/packages/core/src/actions/fees/getDefaultCreatorFees.ts @@ -0,0 +1,50 @@ +import { Contract } from "starknet"; +import { toHex } from "viem"; + +import { Config } from "../../createConfig.js"; + +export const ABI = [ + { + type: "struct", + name: "ark_oz::erc2981::fees::FeesRatio", + members: [ + { name: "numerator", type: "core::integer::u256" }, + { name: "denominator", type: "core::integer::u256" } + ] + }, + { + type: "function", + name: "get_default_creator_fees", + inputs: [], + outputs: [ + { + type: "(core::starknet::contract_address::ContractAddress, ark_oz::erc2981::fees::FeesRatio)" + } + ], + state_mutability: "view" + } +] as const; + +export async function getDefaultCreatorFees(config: Config) { + const contract = new Contract( + ABI, + config.starknetExecutorContract, + config.starknetProvider + ).typedv2(ABI); + + const raw = await contract.get_default_creator_fees(); + const creator = toHex(raw[0] as bigint); + const { numerator, denominator } = raw[1] as { + numerator: bigint; + denominator: bigint; + }; + + return { + creator, + fees: { + formatted: ((Number(numerator) / Number(denominator)) * 100).toFixed(2), + numerator, + denominator + } + }; +} diff --git a/packages/core/src/actions/fees/getFeesAmount.ts b/packages/core/src/actions/fees/getFeesAmount.ts new file mode 100644 index 000000000..7cb3eb0e9 --- /dev/null +++ b/packages/core/src/actions/fees/getFeesAmount.ts @@ -0,0 +1,96 @@ +import { cairo, CallData, Contract } from "starknet"; + +import { Config } from "../../createConfig.js"; + +interface GetFeesAmountParameters { + fulfillBroker: string; + listingBroker: string; + nftAddress: string; + nftTokenId: bigint; + paymentAmount: bigint; +} + +export const GET_FEES_AMOUNT_ABI = [ + { + name: "ark_starknet::interfaces::FeesAmount", + type: "struct", + members: [ + { + name: "fulfill_broker", + type: "core::integer::u256" + }, + { + name: "listing_broker", + type: "core::integer::u256" + }, + { + name: "ark", + type: "core::integer::u256" + }, + { + name: "creator", + type: "core::integer::u256" + } + ] + }, + { + name: "get_fees_amount", + type: "function", + inputs: [ + { + name: "fulfill_broker", + type: "core::starknet::contract_address::ContractAddress" + }, + { + name: "listing_broker", + type: "core::starknet::contract_address::ContractAddress" + }, + { + name: "nft_address", + type: "core::starknet::contract_address::ContractAddress" + }, + { + name: "nft_token_id", + type: "core::integer::u256" + }, + { + name: "payment_amount", + type: "core::integer::u256" + } + ], + outputs: [ + { + type: "ark_starknet::interfaces::FeesAmount" + } + ], + state_mutability: "view" + } +] as const; + +export async function getFeesAmount( + config: Config, + parameters: GetFeesAmountParameters +) { + const contract = new Contract( + GET_FEES_AMOUNT_ABI, + config.starknetExecutorContract, + config.starknetProvider + ).typedv2(GET_FEES_AMOUNT_ABI); + + const callData = CallData.compile({ + fulfill_broker: parameters.fulfillBroker, + listing_broker: parameters.listingBroker, + nft_address: parameters.nftAddress, + nft_token_id: cairo.uint256(parameters.nftTokenId), + payment_amount: cairo.uint256(BigInt(parameters.paymentAmount)) + }); + + const fees = await contract.get_fees_amount(callData); + + return { + ark: fees.ark, + creator: fees.creator, + fulfillBroker: fees.fulfill_broker, + listingBroker: fees.listing_broker + }; +} diff --git a/packages/core/src/actions/fees/index.ts b/packages/core/src/actions/fees/index.ts new file mode 100644 index 000000000..42ba25795 --- /dev/null +++ b/packages/core/src/actions/fees/index.ts @@ -0,0 +1,9 @@ +export { getArkFees } from "./getArkFees.js"; +export { getBrokerFees } from "./getBrokerFees.js"; +export { getCollectionCreatorFees } from "./getCollectionCreatorFees.js"; +export { getDefaultCreatorFees } from "./getDefaultCreatorFees.js"; +export { getFeesAmount } from "./getFeesAmount.js"; +export { setArkFees } from "./setArkFees.js"; +export { setBrokerFees } from "./setBrokerFees.js"; +export { setCollectionCreatorFees } from "./setCollectionCreatorFees.js"; +export { setDefaultCreatorFees } from "./setDefaultCreatorFees.js"; diff --git a/packages/core/src/actions/fees/setArkFees.ts b/packages/core/src/actions/fees/setArkFees.ts new file mode 100644 index 000000000..4ff10b105 --- /dev/null +++ b/packages/core/src/actions/fees/setArkFees.ts @@ -0,0 +1,34 @@ +import { Account, cairo, CallData } from "starknet"; + +import { Config } from "../../createConfig.js"; +import { InvalidFeesRatioError } from "../../errors/actions.js"; +import { validateFeesRatio } from "../../utils/index.js"; + +interface Params { + account: Account; + numerator: number; + denominator: number; +} + +export const setArkFees = async (config: Config, params: Params) => { + if (!validateFeesRatio(params.numerator, params.denominator)) { + throw new InvalidFeesRatioError(); + } + + const result = await params.account.execute({ + contractAddress: config.starknetExecutorContract, + entrypoint: "set_ark_fees", + calldata: CallData.compile({ + fees_ratio: { + numerator: cairo.uint256(params.numerator), + denominator: cairo.uint256(params.denominator) + } + }) + }); + + await config.starknetProvider.waitForTransaction(result.transaction_hash); + + return { + transactionHash: result.transaction_hash + }; +}; diff --git a/packages/core/src/actions/fees/setBrokerFees.ts b/packages/core/src/actions/fees/setBrokerFees.ts new file mode 100644 index 000000000..2d98a4520 --- /dev/null +++ b/packages/core/src/actions/fees/setBrokerFees.ts @@ -0,0 +1,34 @@ +import { Account, cairo, CallData } from "starknet"; + +import { Config } from "../../createConfig.js"; +import { InvalidFeesRatioError } from "../../errors/actions.js"; +import { validateFeesRatio } from "../../utils/index.js"; + +interface Params { + brokerAccount: Account; + numerator: number; + denominator: number; +} + +export const setBrokerFees = async (config: Config, params: Params) => { + if (!validateFeesRatio(params.numerator, params.denominator)) { + throw new InvalidFeesRatioError(); + } + + const result = await params.brokerAccount.execute({ + contractAddress: config.starknetExecutorContract, + entrypoint: "set_broker_fees", + calldata: CallData.compile({ + fees_ratio: { + numerator: cairo.uint256(params.numerator), + denominator: cairo.uint256(params.denominator) + } + }) + }); + + await config.starknetProvider.waitForTransaction(result.transaction_hash); + + return { + transactionHash: result.transaction_hash + }; +}; diff --git a/packages/core/src/actions/fees/setCollectionCreatorFees.ts b/packages/core/src/actions/fees/setCollectionCreatorFees.ts new file mode 100644 index 000000000..26bd795d1 --- /dev/null +++ b/packages/core/src/actions/fees/setCollectionCreatorFees.ts @@ -0,0 +1,41 @@ +import { Account, cairo, CallData } from "starknet"; + +import { Config } from "../../createConfig.js"; +import { InvalidFeesRatioError } from "../../errors/actions.js"; +import { validateFeesRatio } from "../../utils/index.js"; + +interface Params { + account: Account; + tokenAddress: string; + receiver: string; + numerator: number; + denominator: number; +} + +export const setCollectionCreatorFees = async ( + config: Config, + params: Params +) => { + if (!validateFeesRatio(params.numerator, params.denominator)) { + throw new InvalidFeesRatioError(); + } + + const result = await params.account.execute({ + contractAddress: config.starknetExecutorContract, + entrypoint: "set_collection_creator_fees", + calldata: CallData.compile({ + nft_address: params.tokenAddress, + receiver: params.receiver, + fees_ratio: { + numerator: cairo.uint256(params.numerator), + denominator: cairo.uint256(params.denominator) + } + }) + }); + + await config.starknetProvider.waitForTransaction(result.transaction_hash); + + return { + transactionHash: result.transaction_hash + }; +}; diff --git a/packages/core/src/actions/fees/setDefaultCreatorFees.ts b/packages/core/src/actions/fees/setDefaultCreatorFees.ts new file mode 100644 index 000000000..22b5c1f31 --- /dev/null +++ b/packages/core/src/actions/fees/setDefaultCreatorFees.ts @@ -0,0 +1,36 @@ +import { Account, cairo, CallData } from "starknet"; + +import { Config } from "../../createConfig.js"; +import { InvalidFeesRatioError } from "../../errors/actions.js"; +import { validateFeesRatio } from "../../utils/index.js"; + +interface Params { + account: Account; + receiver: string; + numerator: number; + denominator: number; +} + +export const setDefaultCreatorFees = async (config: Config, params: Params) => { + if (!validateFeesRatio(params.numerator, params.denominator)) { + throw new InvalidFeesRatioError(); + } + + const result = await params.account.execute({ + contractAddress: config.starknetExecutorContract, + entrypoint: "set_default_creator_fees", + calldata: CallData.compile({ + receiver: params.receiver, + fees_ratio: { + numerator: cairo.uint256(params.numerator), + denominator: cairo.uint256(params.denominator) + } + }) + }); + + await config.starknetProvider.waitForTransaction(result.transaction_hash); + + return { + transactionHash: result.transaction_hash + }; +}; diff --git a/packages/core/src/actions/order/cancel.ts b/packages/core/src/actions/order/cancel.ts index b14b899c8..1c7b99bd8 100644 --- a/packages/core/src/actions/order/cancel.ts +++ b/packages/core/src/actions/order/cancel.ts @@ -8,7 +8,19 @@ import { } from "starknet"; import { Config } from "../../createConfig.js"; -import { CancelInfo, FullCancelInfo } from "../../types/index.js"; +import { FullCancelInfo } from "../../types/index.js"; + +export interface CancelOrderParameters { + account: AccountInterface; + orderHash: bigint; + tokenAddress: string; + tokenId: bigint; + waitForTransaction?: boolean; +} + +export interface CancelOrderResult { + transactionHash: string; +} /** * Executes a transaction to cancel an order on the Arkchain. @@ -19,7 +31,7 @@ import { CancelInfo, FullCancelInfo } from "../../types/index.js"; * including data compilation, signing, and transaction execution. * * @param {Config} config - The core SDK configuration, including network and contract details. - * @param {cancelOrderParameters} parameters - The parameters required to cancel an order, including: + * @param {CancelOrderParameters} parameters - The parameters required to cancel an order, including: * - starknetAccount: The Starknet account used for signing the transaction. * - arkAccount: The Arkchain account used to execute the cancellation transaction. * - cancelInfo: Information about the order to be cancelled, including the order hash and token details. @@ -29,30 +41,30 @@ import { CancelInfo, FullCancelInfo } from "../../types/index.js"; * * @throws {Error} Throws an error if the contract ABI is not found or if the transaction fails. */ -interface cancelOrderParameters { - starknetAccount: AccountInterface; - cancelInfo: CancelInfo; -} - -const cancelOrder = async ( +export async function cancelOrder( config: Config, - parameters: cancelOrderParameters -) => { - const { starknetAccount, cancelInfo } = parameters; + parameters: CancelOrderParameters +): Promise { + const { + account, + orderHash, + tokenAddress, + tokenId, + waitForTransaction = true + } = parameters; const chainId = await config.starknetProvider.getChainId(); const fullCancelInfo: FullCancelInfo = { - orderHash: cancelInfo.orderHash, - canceller: starknetAccount.address, + orderHash, + canceller: account.address, tokenChainId: chainId, - tokenAddress: cancelInfo.tokenAddress, + tokenAddress: tokenAddress, tokenId: new CairoOption( CairoOptionVariant.Some, - cairo.uint256(cancelInfo.tokenId) + cairo.uint256(tokenId) ) }; - // Execute the transaction - const result = await starknetAccount.execute({ + const result = await account.execute({ contractAddress: config.starknetExecutorContract, entrypoint: "cancel_order", calldata: CallData.compile({ @@ -60,10 +72,13 @@ const cancelOrder = async ( }) }); - // Wait for the transaction to be processed - await config.starknetProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); -}; + if (waitForTransaction) { + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + } -export { cancelOrder }; + return { + transactionHash: result.transaction_hash + }; +} diff --git a/packages/core/src/actions/order/cancelCollectionOffer.ts b/packages/core/src/actions/order/cancelCollectionOffer.ts new file mode 100644 index 000000000..85444b10e --- /dev/null +++ b/packages/core/src/actions/order/cancelCollectionOffer.ts @@ -0,0 +1,78 @@ +import { + AccountInterface, + CairoOption, + CairoOptionVariant, + CallData, + Uint256 +} from "starknet"; + +import { Config } from "../../createConfig.js"; +import { + CancelCollectionOfferInfo, + FullCancelInfo +} from "../../types/index.js"; + +interface CancelOrderResult { + transactionHash: string; +} + +interface cancelOrderParameters { + starknetAccount: AccountInterface; + cancelInfo: CancelCollectionOfferInfo; + waitForTransaction?: boolean; +} + +/** + * Executes a transaction to cancel an order on the Arkchain. + * + * This function manages the cancellation of an order by compiling the cancellation details, + * signing the data using the Starknet account, and executing the transaction through the + * Arkchain account. It handles the complexities involved in the cancellation process, + * including data compilation, signing, and transaction execution. + * + * @param {Config} config - The core SDK configuration, including network and contract details. + * @param {cancelOrderParameters} parameters - The parameters required to cancel an order, including: + * - starknetAccount: The Starknet account used for signing the transaction. + * - arkAccount: The Arkchain account used to execute the cancellation transaction. + * - cancelInfo: Information about the order to be cancelled, including the order hash and token details. + * - owner: (Optional) The owner address for signing purposes. + * + * @returns {Promise} A promise that resolves when the cancellation transaction is successfully processed. + * + * @throws {Error} Throws an error if the contract ABI is not found or if the transaction fails. + */ +async function cancelCollectionOffer( + config: Config, + parameters: cancelOrderParameters +): Promise { + const { starknetAccount, cancelInfo, waitForTransaction = true } = parameters; + const chainId = await config.starknetProvider.getChainId(); + + const fullCancelInfo: FullCancelInfo = { + orderHash: cancelInfo.orderHash, + canceller: starknetAccount.address, + tokenChainId: chainId, + tokenAddress: cancelInfo.tokenAddress, + tokenId: new CairoOption(CairoOptionVariant.None) + }; + + const result = await starknetAccount.execute({ + contractAddress: config.starknetExecutorContract, + entrypoint: "cancel_order", + calldata: CallData.compile({ + order: fullCancelInfo + }) + }); + + if (waitForTransaction) { + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + } + + return { + transactionHash: result.transaction_hash + }; +} + +export { cancelCollectionOffer }; diff --git a/packages/core/src/actions/order/createAuction.ts b/packages/core/src/actions/order/createAuction.ts index 163f32f8f..e55a521c8 100644 --- a/packages/core/src/actions/order/createAuction.ts +++ b/packages/core/src/actions/order/createAuction.ts @@ -9,19 +9,34 @@ import { import { Config } from "../../createConfig.js"; import { - ApproveErc721Info, - AuctionV1, - OrderV1, - RouteType -} from "../../types/index.js"; + EndDateTooFarError, + InvalidEndAmountError, + InvalidEndDateError, + InvalidStartAmountError, + InvalidStartDateError +} from "../../errors/actions.js"; +import { OrderV1, RouteType } from "../../types/index.js"; import { getOrderHashFromOrderV1 } from "../../utils/index.js"; -interface CreateAuctionParameters { - starknetAccount: AccountInterface; - order: AuctionV1; - approveInfo: ApproveErc721Info; +export interface CreateAuctionParameters { + account: AccountInterface; + brokerAddress: string; + tokenAddress: string; + tokenId: bigint; + currencyAddress?: string; + startAmount: bigint; + endAmount?: bigint; + startDate?: number; + endDate?: number; + waitForTransaction?: boolean; } +export interface CreateAuctionResult { + orderHash: bigint; + transactionHash: string; +} + +const docsPath = "/sdk-core/create-auction"; /** * Creates an Auction on the ArkProject. * @@ -36,80 +51,96 @@ interface CreateAuctionParameters { * @returns {Promise} A promise that resolves with the hash of the created order. * */ -const createAuction = async ( +export async function createAuction( config: Config, parameters: CreateAuctionParameters -) => { - const { starknetAccount, order: baseOrder, approveInfo } = parameters; - const currentDate = new Date(); - currentDate.setDate(currentDate.getDate() + 30); - const startDate = baseOrder.startDate || Math.floor(Date.now() / 1000); - const endDate = baseOrder.endDate || Math.floor(currentDate.getTime() / 1000); - const chainId = await config.starknetProvider.getChainId(); +): Promise { + const { + account, + brokerAddress, + tokenAddress, + tokenId, + currencyAddress = config.starknetCurrencyContract, + startAmount, + endAmount, + startDate, + endDate, + waitForTransaction = true + } = parameters; + const now = Math.floor(Date.now() / 1000); + const startedAt = startDate || now; + const endedAt = endDate || now + 60 * 60 * 24; + const maxEndedAt = now + 60 * 60 * 24 * 30; - if (startDate < Math.floor(Date.now() / 1000)) { - throw new Error("Invalid start date"); + if (startedAt < now) { + throw new InvalidStartDateError(startDate, { docsPath }); } - if (endDate < startDate) { - throw new Error("Invalid end date"); + if (endedAt < startedAt) { + throw new InvalidEndDateError({ endDate, startDate }, { docsPath }); } - if (baseOrder.startAmount === BigInt(0)) { - throw new Error("Invalid start amount"); + if (endedAt > maxEndedAt) { + throw new EndDateTooFarError({ endDate, maxEndedAt }, { docsPath }); } - if (baseOrder.endAmount < baseOrder.startAmount) { - throw new Error("Invalid end amount"); + if (startAmount === BigInt(0)) { + throw new InvalidStartAmountError({ docsPath }); } + if (endAmount && endAmount < startAmount) { + throw new InvalidEndAmountError({ docsPath }); + } + + const chainId = await config.starknetProvider.getChainId(); + const order: OrderV1 = { route: RouteType.Erc721ToErc20, - currencyAddress: - baseOrder.currencyAddress ?? config.starknetCurrencyContract, + currencyAddress, currencyChainId: chainId, salt: 1, - offerer: starknetAccount.address, + offerer: account.address, tokenChainId: chainId, - tokenAddress: baseOrder.tokenAddress, + tokenAddress, tokenId: new CairoOption( CairoOptionVariant.Some, - cairo.uint256(baseOrder.tokenId) + cairo.uint256(tokenId) ), quantity: cairo.uint256(1), - startAmount: cairo.uint256(baseOrder.startAmount), - endAmount: cairo.uint256(baseOrder.endAmount || 0), - startDate: startDate, - endDate: endDate, - brokerId: baseOrder.brokerId, + startAmount: cairo.uint256(startAmount), + endAmount: cairo.uint256(endAmount || 0), + startDate: startedAt, + endDate: endedAt, + brokerId: brokerAddress, additionalData: [] }; - const result = await starknetAccount.execute([ + const result = await account.execute([ { - contractAddress: approveInfo.tokenAddress as string, + contractAddress: tokenAddress, entrypoint: "approve", calldata: CallData.compile({ to: config.starknetExecutorContract, - token_id: cairo.uint256(approveInfo.tokenId) + token_id: cairo.uint256(tokenId) }) }, { contractAddress: config.starknetExecutorContract, entrypoint: "create_order", - calldata: CallData.compile({ - order: order - }) + calldata: CallData.compile({ order }) } ]); - await config.starknetProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); + if (waitForTransaction) { + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + } const orderHash = getOrderHashFromOrderV1(order); - return orderHash; -}; - -export { createAuction }; + return { + orderHash, + transactionHash: result.transaction_hash + }; +} diff --git a/packages/core/src/actions/order/createCollectionOffer.ts b/packages/core/src/actions/order/createCollectionOffer.ts new file mode 100644 index 000000000..579ff4072 --- /dev/null +++ b/packages/core/src/actions/order/createCollectionOffer.ts @@ -0,0 +1,144 @@ +import { + AccountInterface, + cairo, + CairoOption, + CairoOptionVariant, + CallData, + Uint256 +} from "starknet"; + +import { Config } from "../../createConfig.js"; +import { + EndDateTooFarError, + InvalidEndDateError, + InvalidStartAmountError, + InvalidStartDateError +} from "../../errors/actions.js"; +import { OrderV1, RouteType } from "../../types/index.js"; +import { getOrderHashFromOrderV1 } from "../../utils/index.js"; +import { getAllowance } from "../read/getAllowance.js"; + +export interface CreateCollectionOfferParameters { + account: AccountInterface; + brokerAddress: string; + currencyAddress?: string; + tokenAddress: string; + amount: bigint; + startDate?: number; + endDate?: number; + waitForTransaction?: boolean; +} + +export interface CreateCollectionOfferResult { + orderHash: bigint; + transactionHash: string; +} + +const docsPath = "/sdk-core/create-collection-offer"; +/** + * Creates a collection offer on the ArkProject. + * + * This function takes a configuration object and listing parameters, builds a complete OrderV1 object + * with default values for unspecified fields, compiles the order data, signs it, and then executes + * the transaction to create a listing on the Arkchain using the specified Starknet and Arkchain accounts. + * + * @param {Config} config - The core SDK config, including network and contract information. + * @param {CreateCollectionOfferParameters} parameters - The parameters for the listing, including Starknet account, + * Arkchain account, base order details, and an optional owner address. + * + * @returns {Promise} A promise that resolves with the hash of the created order. + * + */ +async function createCollectionOffer( + config: Config, + parameters: CreateCollectionOfferParameters +): Promise { + const { + account, + brokerAddress, + currencyAddress = config.starknetCurrencyContract, + tokenAddress, + amount, + startDate, + endDate, + waitForTransaction = true + } = parameters; + const now = Math.floor(Date.now() / 1000); + const startedAt = startDate || now; + const endedAt = endDate || now + 60 * 60 * 24; + const maxEndedAt = now + 60 * 60 * 24 * 30; + + if (startedAt < now) { + throw new InvalidStartDateError(startDate, { docsPath }); + } + + if (endedAt < startedAt) { + throw new InvalidEndDateError({ endDate, startDate }, { docsPath }); + } + + if (endedAt > maxEndedAt) { + throw new EndDateTooFarError({ endDate, maxEndedAt }, { docsPath }); + } + + if (amount === BigInt(0)) { + throw new InvalidStartAmountError({ docsPath }); + } + + const chainId = await config.starknetProvider.getChainId(); + const currentAllowance = await getAllowance( + config, + currencyAddress, + account.address + ); + const allowance = currentAllowance + amount; + const order: OrderV1 = { + route: RouteType.Erc20ToErc721, + currencyAddress, + currencyChainId: chainId, + salt: 1, + offerer: account.address, + tokenChainId: chainId, + tokenAddress, + tokenId: new CairoOption(CairoOptionVariant.None), + quantity: cairo.uint256(1), + startAmount: cairo.uint256(amount), + endAmount: cairo.uint256(0), + startDate: startedAt, + endDate: endedAt, + brokerId: brokerAddress, + additionalData: [] + }; + + const result = await account.execute([ + { + contractAddress: currencyAddress, + entrypoint: "approve", + calldata: CallData.compile({ + spender: config.starknetExecutorContract, + amount: cairo.uint256(allowance) + }) + }, + { + contractAddress: config.starknetExecutorContract, + entrypoint: "create_order", + calldata: CallData.compile({ + order + }) + } + ]); + + if (waitForTransaction) { + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + } + + const orderHash = getOrderHashFromOrderV1(order); + + return { + orderHash, + transactionHash: result.transaction_hash + }; +} + +export { createCollectionOffer }; diff --git a/packages/core/src/actions/order/createListing.ts b/packages/core/src/actions/order/createListing.ts index 76bf43461..8bb727d14 100644 --- a/packages/core/src/actions/order/createListing.ts +++ b/packages/core/src/actions/order/createListing.ts @@ -9,19 +9,32 @@ import { import { Config } from "../../createConfig.js"; import { - ApproveErc721Info, - ListingV1, - OrderV1, - RouteType -} from "../../types/index.js"; + EndDateTooFarError, + InvalidEndDateError, + InvalidStartAmountError, + InvalidStartDateError +} from "../../errors/actions.js"; +import { OrderV1, RouteType } from "../../types/index.js"; import { getOrderHashFromOrderV1 } from "../../utils/index.js"; -interface CreateListingParameters { - starknetAccount: AccountInterface; - order: ListingV1; - approveInfo: ApproveErc721Info; +export interface CreateListingParameters { + account: AccountInterface; + brokerAddress: string; + currencyAddress?: string; + tokenAddress: string; + tokenId: bigint; + amount: bigint; + startDate?: number; + endDate?: number; + waitForTransaction?: boolean; } +export interface CreateListingResult { + orderHash: bigint; + transactionHash: string; +} + +const docsPath = "/sdk-core/create-listing"; /** * Creates a listing on the ArkProject. * @@ -36,64 +49,90 @@ interface CreateListingParameters { * @returns {Promise} A promise that resolves with the hash of the created order. * */ -const createListing = async ( +export async function createListing( config: Config, parameters: CreateListingParameters -) => { - const { starknetAccount, order: baseOrder, approveInfo } = parameters; - const currentDate = new Date(); - currentDate.setDate(currentDate.getDate() + 30); - const startDate = baseOrder.startDate || Math.floor(Date.now() / 1000); - const endDate = baseOrder.endDate || Math.floor(currentDate.getTime() / 1000); - const chainId = await config.starknetProvider.getChainId(); +): Promise { + const { + account, + brokerAddress, + currencyAddress = config.starknetCurrencyContract, + tokenAddress, + tokenId, + amount, + startDate, + endDate, + waitForTransaction = true + } = parameters; + const now = Math.floor(Date.now() / 1000); + const startedAt = startDate || now; + const endedAt = endDate || now + 60 * 60 * 24; + const maxEndedAt = now + 60 * 60 * 24 * 30; + + if (startedAt < now) { + throw new InvalidStartDateError(startDate, { docsPath }); + } + + if (endedAt < startedAt) { + throw new InvalidEndDateError({ endDate, startDate }, { docsPath }); + } + + if (endedAt > maxEndedAt) { + throw new EndDateTooFarError({ endDate, maxEndedAt }, { docsPath }); + } + + if (amount === BigInt(0)) { + throw new InvalidStartAmountError({ docsPath }); + } + const chainId = await config.starknetProvider.getChainId(); const order: OrderV1 = { route: RouteType.Erc721ToErc20, - currencyAddress: - baseOrder.currencyAddress ?? config.starknetCurrencyContract, + currencyAddress, currencyChainId: chainId, salt: 1, - offerer: starknetAccount.address, + offerer: account.address, tokenChainId: chainId, - tokenAddress: baseOrder.tokenAddress, + tokenAddress, tokenId: new CairoOption( CairoOptionVariant.Some, - cairo.uint256(baseOrder.tokenId) + cairo.uint256(tokenId) ), quantity: cairo.uint256(1), - startAmount: cairo.uint256(baseOrder.startAmount), + startAmount: cairo.uint256(amount), endAmount: cairo.uint256(0), - startDate: startDate, - endDate: endDate, - brokerId: baseOrder.brokerId, + startDate: startedAt, + endDate: endedAt, + brokerId: brokerAddress, additionalData: [] }; - const result = await starknetAccount.execute([ + const result = await account.execute([ { - contractAddress: approveInfo.tokenAddress as string, + contractAddress: tokenAddress, entrypoint: "approve", calldata: CallData.compile({ to: config.starknetExecutorContract, - token_id: cairo.uint256(approveInfo.tokenId) + token_id: cairo.uint256(tokenId) }) }, { contractAddress: config.starknetExecutorContract, entrypoint: "create_order", - calldata: CallData.compile({ - order: order - }) + calldata: CallData.compile({ order }) } ]); - await config.starknetProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); + if (waitForTransaction) { + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + } const orderHash = getOrderHashFromOrderV1(order); - return orderHash; -}; - -export { createListing }; + return { + orderHash, + transactionHash: result.transaction_hash + }; +} diff --git a/packages/core/src/actions/order/createOffer.ts b/packages/core/src/actions/order/createOffer.ts index b5e248499..7681c6447 100644 --- a/packages/core/src/actions/order/createOffer.ts +++ b/packages/core/src/actions/order/createOffer.ts @@ -9,20 +9,33 @@ import { import { Config } from "../../createConfig.js"; import { - ApproveErc20Info, - OfferV1, - OrderV1, - RouteType -} from "../../types/index.js"; + EndDateTooFarError, + InvalidEndDateError, + InvalidStartAmountError, + InvalidStartDateError +} from "../../errors/actions.js"; +import { OrderV1, RouteType } from "../../types/index.js"; import { getOrderHashFromOrderV1 } from "../../utils/index.js"; import { getAllowance } from "../read/getAllowance.js"; -interface CreateOfferParameters { - starknetAccount: AccountInterface; - offer: OfferV1; - approveInfo: ApproveErc20Info; +export interface CreateOfferParameters { + account: AccountInterface; + brokerAddress: string; + currencyAddress?: string; + tokenAddress: string; + tokenId?: bigint; + amount: bigint; + startDate?: number; + endDate?: number; + waitForTransaction?: boolean; } +export interface CreateOfferResult { + orderHash: bigint; + transactionHash: string; +} + +const docsPath = "/sdk-core/create-offer"; /** * Creates a listing on the ArkProject. * @@ -34,57 +47,79 @@ interface CreateOfferParameters { * @param {CreateListingParameters} parameters - The parameters for the listing, including Starknet account, * Arkchain account, base order details, and an optional owner address. * - * @returns {Promise} A promise that resolves with the hash of the created order. + * @returns {Promise} A promise that resolves with the hash of the created order. * */ -const createOffer = async ( +export async function createOffer( config: Config, parameters: CreateOfferParameters -) => { - const { starknetAccount, offer: baseOrder, approveInfo } = parameters; - const currentDate = new Date(); - currentDate.setDate(currentDate.getDate() + 30); - const startDate = baseOrder.startDate || Math.floor(Date.now() / 1000); - const endDate = baseOrder.endDate || Math.floor(currentDate.getTime() / 1000); - const currencyAddress = - baseOrder.currencyAddress || config.starknetCurrencyContract; +): Promise { + const { + account, + brokerAddress, + currencyAddress = config.starknetCurrencyContract, + tokenAddress, + tokenId, + amount, + startDate, + endDate, + waitForTransaction = true + } = parameters; + const now = Math.floor(Date.now() / 1000); + const startedAt = startDate || now; + const endedAt = endDate || now + 60 * 60 * 24; + const maxEndedAt = now + 60 * 60 * 24 * 30; + + if (startedAt < Math.floor(Date.now() / 1000)) { + throw new InvalidStartDateError(startDate, { docsPath }); + } - if (currencyAddress !== approveInfo.currencyAddress) { - throw new Error("Invalid currency address, offer and approveInfo mismatch"); + if (endedAt < startedAt) { + throw new InvalidEndDateError({ endDate, startDate }, { docsPath }); + } + + if (endedAt > maxEndedAt) { + throw new EndDateTooFarError({ endDate, maxEndedAt }, { docsPath }); + } + + if (amount === BigInt(0)) { + throw new InvalidStartAmountError({ docsPath }); } const chainId = await config.starknetProvider.getChainId(); const currentAllowance = await getAllowance( config, - approveInfo.currencyAddress, - starknetAccount.address + currencyAddress, + account.address ); - const allowance = currentAllowance + approveInfo.amount; + + const allowance = currentAllowance + amount; const order: OrderV1 = { route: RouteType.Erc20ToErc721, - currencyAddress: - baseOrder.currencyAddress ?? config.starknetCurrencyContract, + currencyAddress, currencyChainId: chainId, salt: 1, - offerer: starknetAccount.address, + offerer: account.address, tokenChainId: chainId, - tokenAddress: baseOrder.tokenAddress, - tokenId: new CairoOption( - CairoOptionVariant.Some, - cairo.uint256(baseOrder.tokenId) - ), + tokenAddress, + tokenId: tokenId + ? new CairoOption( + CairoOptionVariant.Some, + cairo.uint256(tokenId) + ) + : new CairoOption(CairoOptionVariant.None, cairo.uint256(0)), quantity: cairo.uint256(1), - startAmount: cairo.uint256(baseOrder.startAmount), + startAmount: cairo.uint256(amount), endAmount: cairo.uint256(0), - startDate: startDate, - endDate: endDate, - brokerId: baseOrder.brokerId, + startDate: startedAt, + endDate: endedAt, + brokerId: brokerAddress, additionalData: [] }; - const result = await starknetAccount.execute([ + const result = await account.execute([ { - contractAddress: approveInfo.currencyAddress, + contractAddress: currencyAddress, entrypoint: "approve", calldata: CallData.compile({ spender: config.starknetExecutorContract, @@ -100,13 +135,16 @@ const createOffer = async ( } ]); - await config.starknetProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); + if (waitForTransaction) { + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + } const orderHash = getOrderHashFromOrderV1(order); - return orderHash; -}; - -export { createOffer }; + return { + orderHash, + transactionHash: result.transaction_hash + }; +} diff --git a/packages/core/src/actions/order/fulfillAuction.ts b/packages/core/src/actions/order/fulfillAuction.ts index b53de9f04..3c5abb294 100644 --- a/packages/core/src/actions/order/fulfillAuction.ts +++ b/packages/core/src/actions/order/fulfillAuction.ts @@ -8,7 +8,23 @@ import { } from "starknet"; import { Config } from "../../createConfig.js"; -import { FulfillAuctionInfo, FulfillInfo } from "../../types/index.js"; +import { FulfillInfo } from "../../types/index.js"; + +export interface FulfillAuctionParameters { + account: AccountInterface; + brokerAddress: string; + orderHash: bigint; + relatedOrderHash: bigint; + tokenAddress: string; + tokenId: bigint; + quantity: bigint; + currencyAddress?: string; + waitForTransaction?: boolean; +} + +export interface FulfillAuctionResult { + transactionHash: string; +} /** * Fulfill an auction on the Arkchain. @@ -18,35 +34,40 @@ import { FulfillAuctionInfo, FulfillInfo } from "../../types/index.js"; * * @returns {Promise} A promise that resolves when the transaction is completed. */ -interface FulfillAuctionParameters { - starknetAccount: AccountInterface; - fulfillAuctionInfo: FulfillAuctionInfo; -} - -const fulfillAuction = async ( +export async function fulfillAuction( config: Config, parameters: FulfillAuctionParameters -) => { - const { starknetAccount, fulfillAuctionInfo } = parameters; +): Promise { + const { + account, + brokerAddress, + orderHash, + relatedOrderHash, + tokenAddress, + tokenId, + quantity, + waitForTransaction = true + } = parameters; const chainId = await config.starknetProvider.getChainId(); const fulfillInfo: FulfillInfo = { - orderHash: fulfillAuctionInfo.orderHash, + orderHash, relatedOrderHash: new CairoOption( CairoOptionVariant.Some, - fulfillAuctionInfo.relatedOrderHash + relatedOrderHash ), - fulfiller: starknetAccount.address, + fulfiller: account.address, tokenChainId: chainId, - tokenAddress: fulfillAuctionInfo.tokenAddress, + tokenAddress, tokenId: new CairoOption( CairoOptionVariant.Some, - cairo.uint256(fulfillAuctionInfo.tokenId) + cairo.uint256(tokenId) ), - fulfillBrokerAddress: fulfillAuctionInfo.brokerId + quantity: cairo.uint256(quantity), + fulfillBrokerAddress: brokerAddress }; - const result = await starknetAccount.execute([ + const result = await account.execute([ { contractAddress: config.starknetExecutorContract, entrypoint: "fulfill_order", @@ -56,9 +77,13 @@ const fulfillAuction = async ( } ]); - await config.starknetProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); -}; + if (waitForTransaction) { + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + } -export { fulfillAuction }; + return { + transactionHash: result.transaction_hash + }; +} diff --git a/packages/core/src/actions/order/fulfillListing.ts b/packages/core/src/actions/order/fulfillListing.ts index b8296309f..f3a7b2219 100644 --- a/packages/core/src/actions/order/fulfillListing.ts +++ b/packages/core/src/actions/order/fulfillListing.ts @@ -8,56 +8,73 @@ import { } from "starknet"; import { Config } from "../../createConfig.js"; -import { - ApproveErc20Info, - FulfillInfo, - FulfillListingInfo -} from "../../types/index.js"; +import { FulfillInfo } from "../../types/index.js"; import { getAllowance } from "../read/getAllowance.js"; +export interface FulfillListingParameters { + account: AccountInterface; + brokerAddress: string; + currencyAddress?: string; + orderHash: bigint; + tokenAddress: string; + tokenId: bigint; + quantity: bigint; + amount: bigint; + waitForTransaction?: boolean; +} + +export type FulfillListingResult = { + transactionHash: string; +}; + /** * Fulfill a listing on the Arkchain. * * @param {Config} config - The core SDK configuration. * @param {FulfillListingParameters} parameters - Parameters for fulfilling the listing. * - * @returns {Promise} A promise that resolves when the transaction is completed. + * @returns {Promise} A promise that resolves when the transaction is completed. */ -interface FulfillListingParameters { - starknetAccount: AccountInterface; - fulfillListingInfo: FulfillListingInfo; - approveInfo: ApproveErc20Info; -} - -const fulfillListing = async ( +export async function fulfillListing( config: Config, parameters: FulfillListingParameters -) => { - const { starknetAccount, fulfillListingInfo, approveInfo } = parameters; +): Promise { + const { + account, + brokerAddress, + currencyAddress = config.starknetCurrencyContract, + orderHash, + tokenAddress, + tokenId, + quantity, + amount, + waitForTransaction = true + } = parameters; const chainId = await config.starknetProvider.getChainId(); const currentAllowance = await getAllowance( config, - approveInfo.currencyAddress, - starknetAccount.address + currencyAddress, + account.address ); - const allowance = currentAllowance + approveInfo.amount; + const allowance = currentAllowance + amount; const fulfillInfo: FulfillInfo = { - orderHash: fulfillListingInfo.orderHash, + orderHash, relatedOrderHash: new CairoOption(CairoOptionVariant.None), - fulfiller: starknetAccount.address, + fulfiller: account.address, tokenChainId: chainId, - tokenAddress: fulfillListingInfo.tokenAddress, + tokenAddress, tokenId: new CairoOption( CairoOptionVariant.Some, - cairo.uint256(fulfillListingInfo.tokenId) + cairo.uint256(tokenId) ), - fulfillBrokerAddress: fulfillListingInfo.brokerId + quantity: cairo.uint256(quantity), + fulfillBrokerAddress: brokerAddress }; - const result = await starknetAccount.execute([ + const result = await account.execute([ { - contractAddress: approveInfo.currencyAddress as string, + contractAddress: currencyAddress, entrypoint: "approve", calldata: CallData.compile({ spender: config.starknetExecutorContract, @@ -73,10 +90,13 @@ const fulfillListing = async ( } ]); - // Wait for the transaction to be processed - await config.starknetProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); -}; + if (waitForTransaction) { + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + } -export { fulfillListing }; + return { + transactionHash: result.transaction_hash + }; +} diff --git a/packages/core/src/actions/order/fulfillOffer.ts b/packages/core/src/actions/order/fulfillOffer.ts index cd5b37d5b..96937c685 100644 --- a/packages/core/src/actions/order/fulfillOffer.ts +++ b/packages/core/src/actions/order/fulfillOffer.ts @@ -8,11 +8,21 @@ import { } from "starknet"; import { Config } from "../../createConfig.js"; -import { - ApproveErc721Info, - FulfillInfo, - FulfillOfferInfo -} from "../../types/index.js"; +import { FulfillInfo } from "../../types/index.js"; + +export interface FulfillOfferParameters { + account: AccountInterface; + brokerAddress: string; + orderHash: bigint; + tokenAddress: string; + tokenId: bigint; + quantity: bigint; + waitForTransaction?: boolean; +} + +export interface FulfillOfferResult { + transactionHash: string; +} /** * Fulfill an offer on the Arkchain. @@ -22,38 +32,42 @@ import { * * @returns {Promise} A promise that resolves when the transaction is completed. */ -interface FulfillOfferParameters { - starknetAccount: AccountInterface; - fulfillOfferInfo: FulfillOfferInfo; - approveInfo: ApproveErc721Info; -} - -const fulfillOffer = async ( +export async function fulfillOffer( config: Config, parameters: FulfillOfferParameters -) => { - const { starknetAccount, fulfillOfferInfo, approveInfo } = parameters; +): Promise { + const { + account, + brokerAddress, + orderHash, + tokenAddress, + tokenId, + quantity, + waitForTransaction = true + } = parameters; const chainId = await config.starknetProvider.getChainId(); + const fulfillInfo: FulfillInfo = { - orderHash: fulfillOfferInfo.orderHash, + orderHash, relatedOrderHash: new CairoOption(CairoOptionVariant.None), - fulfiller: starknetAccount.address, + fulfiller: account.address, tokenChainId: chainId, - tokenAddress: fulfillOfferInfo.tokenAddress, + tokenAddress, tokenId: new CairoOption( CairoOptionVariant.Some, - cairo.uint256(fulfillOfferInfo.tokenId) + cairo.uint256(tokenId) ), - fulfillBrokerAddress: fulfillOfferInfo.brokerId + quantity: cairo.uint256(quantity), + fulfillBrokerAddress: brokerAddress }; - const result = await starknetAccount.execute([ + const result = await account.execute([ { - contractAddress: approveInfo.tokenAddress as string, + contractAddress: tokenAddress, entrypoint: "approve", calldata: CallData.compile({ to: config.starknetExecutorContract, - token_id: cairo.uint256(approveInfo.tokenId) + token_id: cairo.uint256(tokenId) }) }, { @@ -65,10 +79,13 @@ const fulfillOffer = async ( } ]); - // Wait for the transaction to be processed - await config.starknetProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); -}; + if (waitForTransaction) { + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + } -export { fulfillOffer }; + return { + transactionHash: result.transaction_hash + }; +} diff --git a/packages/core/src/actions/order/index.ts b/packages/core/src/actions/order/index.ts index 61c18b0c1..44225fd73 100644 --- a/packages/core/src/actions/order/index.ts +++ b/packages/core/src/actions/order/index.ts @@ -1,7 +1,48 @@ -export { createListing } from "./createListing.js"; -export { createAuction } from "./createAuction.js"; -export { createOffer } from "./createOffer.js"; -export { cancelOrder } from "./cancel.js"; -export { fulfillListing } from "./fulfillListing.js"; -export { fulfillAuction } from "./fulfillAuction.js"; -export { fulfillOffer } from "./fulfillOffer.js"; +export { + createListing, + type CreateListingParameters, + type CreateListingResult +} from "./createListing.js"; + +export { + createAuction, + type CreateAuctionParameters, + type CreateAuctionResult +} from "./createAuction.js"; + +export { + createOffer, + type CreateOfferParameters, + type CreateOfferResult +} from "./createOffer.js"; + +export { + cancelOrder, + type CancelOrderParameters, + type CancelOrderResult +} from "./cancel.js"; + +export { + fulfillListing, + type FulfillListingParameters, + type FulfillListingResult +} from "./fulfillListing.js"; + +export { + fulfillAuction, + type FulfillAuctionParameters, + type FulfillAuctionResult +} from "./fulfillAuction.js"; + +export { cancelCollectionOffer } from "./cancelCollectionOffer.js"; +export { + createCollectionOffer, + type CreateCollectionOfferParameters, + type CreateCollectionOfferResult +} from "./createCollectionOffer.js"; + +export { + fulfillOffer, + type FulfillOfferParameters, + type FulfillOfferResult +} from "./fulfillOffer.js"; diff --git a/packages/core/src/actions/read/getAllowance.ts b/packages/core/src/actions/read/getAllowance.ts index 7ff5ba034..d01880e1b 100644 --- a/packages/core/src/actions/read/getAllowance.ts +++ b/packages/core/src/actions/read/getAllowance.ts @@ -1,6 +1,7 @@ import { Contract } from "starknet"; import { Config } from "../../createConfig.js"; +import { NoABIError } from "../../errors/actions.js"; export const getAllowance = async ( config: Config, @@ -10,7 +11,7 @@ export const getAllowance = async ( const { abi } = await config.starknetProvider.getClassAt(ERC20ContractAddress); if (abi === undefined) { - throw new Error("no abi."); + throw new NoABIError({ docsPath: "/sdk-core/fulfill-listing" }); } const ERC20Contract = new Contract( diff --git a/packages/core/src/actions/read/getNFTOwner.ts b/packages/core/src/actions/read/getNFTOwner.ts index 331c79b50..c63a2d17f 100644 --- a/packages/core/src/actions/read/getNFTOwner.ts +++ b/packages/core/src/actions/read/getNFTOwner.ts @@ -1,6 +1,7 @@ import { cairo, CallData, Contract } from "starknet"; import { Config } from "../../createConfig.js"; +import { NoABIError } from "../../errors/actions.js"; export const getNftOwner = async ( config: Config, @@ -9,7 +10,7 @@ export const getNftOwner = async ( ) => { const { abi } = await config.starknetProvider.getClassAt(nftContractAddress); if (abi === undefined) { - throw new Error("no abi."); + throw new NoABIError({ docsPath: "/sdk-core/get-nft-owner" }); } const nftContract = new Contract( diff --git a/packages/core/src/actions/read/getOrder.ts b/packages/core/src/actions/read/getOrder.ts index ed9ea062e..8820991b1 100644 --- a/packages/core/src/actions/read/getOrder.ts +++ b/packages/core/src/actions/read/getOrder.ts @@ -1,6 +1,7 @@ import { CallData, Contract } from "starknet"; import { Config } from "../../createConfig.js"; +import { NoABIError } from "../../errors/actions.js"; interface GetOrderParameters { orderHash: bigint; @@ -8,17 +9,17 @@ interface GetOrderParameters { const getOrder = async (config: Config, parameters: GetOrderParameters) => { const { orderHash } = parameters; - const { abi: orderbookAbi } = await config.arkProvider.getClassAt( - config.arkchainOrderbookContract + const { abi: orderbookAbi } = await config.starknetProvider.getClassAt( + config.starknetExecutorContract ); if (orderbookAbi === undefined) { - throw new Error("no abi."); + throw new NoABIError({ docsPath: "/sdk-core/get-order" }); } const orderbookContract = new Contract( orderbookAbi, - config.arkchainOrderbookContract, - config.arkProvider + config.starknetExecutorContract, + config.starknetProvider ); const order_hash_calldata = CallData.compile({ diff --git a/packages/core/src/actions/read/getOrderHash.ts b/packages/core/src/actions/read/getOrderHash.ts index 356f0aa89..98d164c26 100644 --- a/packages/core/src/actions/read/getOrderHash.ts +++ b/packages/core/src/actions/read/getOrderHash.ts @@ -2,6 +2,7 @@ import * as starknet from "@scure/starknet"; import { cairo, CallData, Contract, shortString } from "starknet"; import { Config } from "../../createConfig.js"; +import { NoABIError } from "../../errors/actions.js"; interface GetOrderHashParameters { tokenId: bigint; @@ -16,7 +17,7 @@ const getOrderHash = async ( const chainId = await config.starknetProvider.getChainId(); const tokenHash = { tokenId: cairo.uint256(tokenId), - tokenAddress: tokenAddress, + tokenAddress, tokenChainId: shortString.decodeShortString(chainId.toString()) }; @@ -29,17 +30,17 @@ const getOrderHash = async ( const tokenHashMessage = starknet.poseidonHashMany(tokenHashBigIntArray); - const { abi: orderbookAbi } = await config.arkProvider.getClassAt( - config.arkchainOrderbookContract + const { abi: executorAbi } = await config.starknetProvider.getClassAt( + config.starknetExecutorContract ); - if (orderbookAbi === undefined) { - throw new Error("no abi."); + if (executorAbi === undefined) { + throw new NoABIError({ docsPath: "/sdk-core/get-order-hash" }); } const orderbookContract = new Contract( - orderbookAbi, - config.arkchainOrderbookContract, - config.arkProvider + executorAbi, + config.starknetExecutorContract, + config.starknetProvider ); const order_hash_calldata = CallData.compile({ diff --git a/packages/core/src/actions/read/getOrderSigner.ts b/packages/core/src/actions/read/getOrderSigner.ts index 0c08005cf..dfcccc714 100644 --- a/packages/core/src/actions/read/getOrderSigner.ts +++ b/packages/core/src/actions/read/getOrderSigner.ts @@ -1,6 +1,7 @@ import { CallData, Contract } from "starknet"; import { Config } from "../../createConfig.js"; +import { NoABIError } from "../../errors/actions.js"; interface GetOrderSignerParameters { orderHash: bigint; @@ -11,17 +12,17 @@ const getOrderSigner = async ( parameters: GetOrderSignerParameters ) => { const { orderHash } = parameters; - const { abi: orderbookAbi } = await config.arkProvider.getClassAt( - config.arkchainOrderbookContract + const { abi: executorAbi } = await config.starknetProvider.getClassAt( + config.starknetExecutorContract ); - if (orderbookAbi === undefined) { - throw new Error("no abi."); + if (executorAbi === undefined) { + throw new NoABIError({ docsPath: "/sdk-core/get-order-signer" }); } const orderbookContract = new Contract( - orderbookAbi, - config.arkchainOrderbookContract, - config.arkProvider + executorAbi, + config.starknetExecutorContract, + config.starknetProvider ); const order_hash_calldata = CallData.compile({ diff --git a/packages/core/src/actions/read/getOrderStatus.ts b/packages/core/src/actions/read/getOrderStatus.ts index d5c74f879..0a61eb6e3 100644 --- a/packages/core/src/actions/read/getOrderStatus.ts +++ b/packages/core/src/actions/read/getOrderStatus.ts @@ -1,6 +1,7 @@ import { CairoCustomEnum, CallData, Contract } from "starknet"; import { Config } from "../../createConfig.js"; +import { NoABIError } from "../../errors/actions.js"; interface GetOrderStatusParameters { orderHash: bigint; @@ -11,17 +12,17 @@ const getOrderStatus = async ( parameters: GetOrderStatusParameters ) => { const { orderHash } = parameters; - const { abi: orderbookAbi } = await config.arkProvider.getClassAt( - config.arkchainOrderbookContract + const { abi: executorAbi } = await config.starknetProvider.getClassAt( + config.starknetExecutorContract ); - if (orderbookAbi === undefined) { - throw new Error("no abi."); + if (executorAbi === undefined) { + throw new NoABIError({ docsPath: "/sdk-core/get-order-status" }); } const orderbookContract = new Contract( - orderbookAbi, - config.arkchainOrderbookContract, - config.arkProvider + executorAbi, + config.starknetExecutorContract, + config.starknetProvider ); const order_hash_calldata = CallData.compile({ diff --git a/packages/core/src/actions/read/getOrderType.ts b/packages/core/src/actions/read/getOrderType.ts index 9d7175bd1..48ecf4c8b 100644 --- a/packages/core/src/actions/read/getOrderType.ts +++ b/packages/core/src/actions/read/getOrderType.ts @@ -1,6 +1,7 @@ import { CairoCustomEnum, CallData, Contract } from "starknet"; import { Config } from "../../createConfig.js"; +import { NoABIError } from "../../errors/actions.js"; interface GetOrderTypeParameters { orderHash: bigint; @@ -11,17 +12,17 @@ const getOrderType = async ( parameters: GetOrderTypeParameters ) => { const { orderHash } = parameters; - const { abi: orderbookAbi } = await config.arkProvider.getClassAt( - config.arkchainOrderbookContract + const { abi: executorAbi } = await config.starknetProvider.getClassAt( + config.starknetExecutorContract ); - if (orderbookAbi === undefined) { - throw new Error("no abi."); + if (executorAbi === undefined) { + throw new NoABIError({ docsPath: "/sdk-core/get-order-type" }); } const orderbookContract = new Contract( - orderbookAbi, - config.arkchainOrderbookContract, - config.arkProvider + executorAbi, + config.starknetExecutorContract, + config.starknetProvider ); const order_hash_calldata = CallData.compile({ diff --git a/packages/core/src/actions/read/index.ts b/packages/core/src/actions/read/index.ts index 781cfb196..9384f333f 100644 --- a/packages/core/src/actions/read/index.ts +++ b/packages/core/src/actions/read/index.ts @@ -1,6 +1,6 @@ -export { getOrderHash } from "./getOrderHash.js"; +export { getAllowance } from "./getAllowance.js"; export { getOrder } from "./getOrder.js"; -export { getOrderStatus } from "./getOrderStatus.js"; +export { getOrderHash } from "./getOrderHash.js"; export { getOrderSigner } from "./getOrderSigner.js"; +export { getOrderStatus } from "./getOrderStatus.js"; export { getOrderType } from "./getOrderType.js"; -export { getAllowance } from "./getAllowance.js"; diff --git a/packages/core/src/constants.ts b/packages/core/src/constants.ts index 09720cbc8..ded638ddf 100644 --- a/packages/core/src/constants.ts +++ b/packages/core/src/constants.ts @@ -27,11 +27,5 @@ export const starknetExecutorContracts = { export const starknetEthContract = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"; -export const arkchainOrderbookContracts = { - mainnet: MAINNET_CONTRACTS.orderbook, - sepolia: SEPOLIA_CONTRACTS.orderbook, - dev: "" -}; - export const SOLIS_ACCOUNT_CLASS_HASH = "0x05400e90f7e0ae78bd02c77cd75527280470e2fe19c54970dd79dc37a9d3645c"; diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index 03267bbe1..d9c53f06c 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -1,14 +1,8 @@ // This file is auto-generated. Do not edit directly. export const SEPOLIA_CONTRACTS = { - messaging: - "0x74f13f1dffb5ad3c051d535ba03514e653b6dcac68e30b2db66a0aa0217c815", - executor: "0xb86ab357c15c12fb78f9b0a19fa974c730fcbab96f17881827dde871665f0b", - orderbook: "0x795b605fa3144afd6f11a4499f71b9cf373bcba3f1b2835d51f65ab59392261" + "executor": "0xb86ab357c15c12fb78f9b0a19fa974c730fcbab96f17881827dde871665f0b" }; export const MAINNET_CONTRACTS = { - messaging: - "0x57d45cc46de463f7ae63b74ce9b6b6b496a1178b02e7ad04d7c307caa698b7b", - executor: "0x7b42945bc47001db92fe1b9739d753925263f2f1036c2ae1f87536c916ee6a", - orderbook: "0x5add3084bb8664eb2a641cf26a28f60588c3ccd63af0632aafefcbb2332c345" + "executor": "0x56ea156367ba964adac5e84d61b89fadf262074c9b272ba415d8b13cb461ab8" }; diff --git a/packages/core/src/createConfig.ts b/packages/core/src/createConfig.ts index 4d42d93d6..316c117f8 100644 --- a/packages/core/src/createConfig.ts +++ b/packages/core/src/createConfig.ts @@ -1,13 +1,12 @@ import { RpcProvider, type ProviderInterface } from "starknet"; import { - arkchainOrderbookContracts, - arkchainRpcUrls, networks, starknetEthContract, starknetExecutorContracts, starknetRpcUrls } from "./constants.js"; +import { MissingExecutorContractError } from "./errors/config.js"; export type Network = "mainnet" | "sepolia" | "dev"; @@ -17,10 +16,6 @@ export interface Config { starknetRpcUrl: string; starknetExecutorContract: string; starknetCurrencyContract: string; - arkchainNetwork: Network; - arkProvider: ProviderInterface; - arkchainRpcUrl: string; - arkchainOrderbookContract: string; } export type CreateConfigParameters = { @@ -29,29 +24,19 @@ export type CreateConfigParameters = { starknetProvider?: ProviderInterface; starknetExecutorContract?: string; starknetCurrencyContract?: string; - arkchainNetwork: Network; - arkchainRpcUrl?: string; - arkProvider?: ProviderInterface; - arkchainOrderbookContract?: string; }; +const docsPath = "/sdk-core/configuration"; +const docsSlug = "starknetExecutorContract"; export function createConfig({ starknetNetwork, starknetRpcUrl, starknetProvider, starknetExecutorContract, - starknetCurrencyContract = starknetEthContract, - arkchainNetwork, - arkchainRpcUrl, - arkProvider, - arkchainOrderbookContract + starknetCurrencyContract = starknetEthContract }: CreateConfigParameters): Config { if (starknetNetwork === networks.dev && !starknetExecutorContract) { - throw new Error("starknetExecutorContract is required for dev network"); - } - - if (arkchainNetwork === networks.dev && !arkchainOrderbookContract) { - throw new Error("arkchainOrderbookContract is required for dev network"); + throw new MissingExecutorContractError({ docsPath, docsSlug }); } return { @@ -64,15 +49,6 @@ export function createConfig({ }), starknetExecutorContract: starknetExecutorContract || starknetExecutorContracts[starknetNetwork], - starknetCurrencyContract, - arkchainNetwork, - arkchainRpcUrl: arkchainRpcUrl || arkchainRpcUrls[arkchainNetwork], - arkProvider: - arkProvider || - new RpcProvider({ - nodeUrl: arkchainRpcUrl || arkchainRpcUrls[arkchainNetwork] - }), - arkchainOrderbookContract: - arkchainOrderbookContract || arkchainOrderbookContracts[arkchainNetwork] + starknetCurrencyContract }; } diff --git a/packages/core/src/errors/account.ts b/packages/core/src/errors/account.ts new file mode 100644 index 000000000..48043ac4c --- /dev/null +++ b/packages/core/src/errors/account.ts @@ -0,0 +1,18 @@ +import { BaseError, BaseErrorOptions } from "./base.js"; + +export type NoAccountFoundErrorType = NoAccountFoundError & { + name: "NoAccountFoundError"; +}; +export class NoAccountFoundError extends BaseError { + override name = "NoAccountFoundError"; + constructor({ docsPath, docsSlug }: BaseErrorOptions) { + super("No account found", { docsPath, docsSlug }); + } +} + +export class AccountNotConnectedError extends BaseError { + override name = "AccountNotConnectedError"; + constructor({ docsPath, docsSlug }: BaseErrorOptions) { + super("Account not connected", { docsPath, docsSlug }); + } +} diff --git a/packages/core/src/errors/actions.ts b/packages/core/src/errors/actions.ts new file mode 100644 index 000000000..e037678b8 --- /dev/null +++ b/packages/core/src/errors/actions.ts @@ -0,0 +1,121 @@ +import { BaseError, BaseErrorOptions } from "./base.js"; + +export type UndefinedNFTContractAddressErrorType = + UndefinedNFTContractAddressError & { + name: "UndefinedNFTContractAddressErrorType"; + }; +export class UndefinedNFTContractAddressError extends BaseError { + override name = "UndefinedNFTContractAddressError"; + constructor({ docsPath, docsSlug }: BaseErrorOptions) { + super("NFT contract address is not defined", { docsPath, docsSlug }); + } +} + +export type NoABIErrorType = NoABIError & { + name: "NoABIError"; +}; +export class NoABIError extends BaseError { + override name = "NoABIError"; + constructor({ docsPath, docsSlug }: BaseErrorOptions) { + super("No ABI", { docsPath, docsSlug }); + } +} + +export type AccountDeployFailedErrorType = AccountDeployFailedError & { + name: "AccountDeployFailedError"; +}; +export class AccountDeployFailedError extends BaseError { + override name = "AccountDeployFailedError"; + constructor(address: string, { docsPath }: BaseErrorOptions) { + super(`Account deploy failed for ${address}`, { docsPath }); + } +} + +export type InvalidFeesRatioErrorType = InvalidFeesRatioError & { + name: "InvalidFeesRatioError"; +}; +export class InvalidFeesRatioError extends BaseError { + override name = "InvalidFeesRatioError"; + constructor() { + super("Invalid fees ratio", { + docsPath: "/errors", + docsSlug: "error-types" + }); + } +} + +export type InvalidStartDateErrorType = InvalidFeesRatioError & { + name: "InvalidStartDateErrorType"; +}; +export class InvalidStartDateError extends BaseError { + override name = "InvalidStartDateError"; + constructor(startDate: number | undefined, { docsPath }: BaseErrorOptions) { + super( + `Invalid start date. Start date (${startDate}) cannot be in the past.`, + { docsPath } + ); + } +} + +export type InvalidEndDateErrorType = InvalidEndDateError & { + name: "InvalidDateError"; +}; +export class InvalidEndDateError extends BaseError { + override name = "InvalidEndDateError"; + constructor( + { + endDate, + startDate + }: { endDate: number | undefined; startDate: number | undefined }, + { docsPath }: BaseErrorOptions + ) { + super( + `Invalid end date. End date (${endDate}) must be after the start date (${startDate}).`, + { docsPath } + ); + } +} + +export type EndDateTooFarErrorType = EndDateTooFarError & { + name: "EndDateTooFarError"; +}; +export class EndDateTooFarError extends BaseError { + override name = "EndDateTooFarError"; + constructor( + { + endDate, + maxEndedAt + }: { endDate: number | undefined; maxEndedAt: number | undefined }, + { docsPath }: BaseErrorOptions + ) { + super( + `End date too far in the future. End date (${endDate}) exceeds the maximum allowed (${maxEndedAt}).`, + { docsPath } + ); + } +} + +export type InvalidStartAmountErrorType = InvalidStartAmountError & { + name: "InvalidStartAmountError"; +}; +export class InvalidStartAmountError extends BaseError { + override name = "InvalidStartAmountError"; + constructor({ docsPath }: BaseErrorOptions) { + super("Invalid start amount. The start amount must be greater than zero.", { + docsPath + }); + } +} + +export type InvalidEndAmountErrorType = InvalidEndAmountError & { + name: "InvalidEndAmountErrorType"; +}; +export class InvalidEndAmountError extends BaseError { + override name = "InvalidEndAmountError"; + constructor({ docsPath }: BaseErrorOptions) { + super( + "Invalid end amount. The end amount must be greater than the start amount.", + { docsPath } + ); + } +} diff --git a/packages/core/src/errors/base.ts b/packages/core/src/errors/base.ts new file mode 100644 index 000000000..62745b443 --- /dev/null +++ b/packages/core/src/errors/base.ts @@ -0,0 +1,95 @@ +import { Compute, OneOf } from "../types/utils.js"; +import { getVersion } from "../utils/utils.js"; + +export type ErrorType = Error & { name: name }; + +export type BaseErrorOptions = Compute< + OneOf<{ details?: string | undefined } | { cause: BaseError | Error }> & { + docsPath?: string | undefined; + docsSlug?: string | undefined; + metaMessages?: string[] | undefined; + } +>; + +export type BaseErrorType = BaseError & { name: "ArkProjectCoreError" }; +export class BaseError extends Error { + details: string; + docsPath?: string | undefined; + metaMessages?: string[] | undefined; + shortMessage: string; + + override name = "ArkProjectCoreError"; + get docsBaseUrl() { + return "https://docs.arkproject.dev/"; + } + get version() { + return getVersion(); + } + + constructor(shortMessage: string, options: BaseErrorOptions = {}) { + super(); + + const details = + options.cause instanceof BaseError + ? options.cause.details + : options.cause?.message + ? options.cause?.message + : options.details!; + const docsPath = + options.cause instanceof BaseError + ? options.cause.docsPath || options.docsPath + : options.docsPath; + + this.message = [ + shortMessage || "An error occured.", + "", + ...(options.metaMessages ? [...options.metaMessages, ""] : []), + ...(docsPath + ? [ + `Docs: ${this.docsBaseUrl}${docsPath}${options.docsSlug ? `#${options.docsSlug}` : ""}` + ] + : []), + ...(details ? [`Details: ${details}`] : []), + `Version: ${this.version}` + ].join("\n"); + + if (options.cause) this.cause = options.cause; + this.details = details; + this.docsPath = docsPath; + this.metaMessages = options.metaMessages; + this.shortMessage = shortMessage; + } + + walk(fn?: (err: unknown) => boolean) { + return this.#walk(this, fn); + } + + #walk(err: unknown, fn?: (err: unknown) => boolean): unknown { + if (fn?.(err)) return err; + if ((err as Error).cause) return this.#walk((err as Error).cause, fn); + return err; + } +} + +/** + * CONTRACT_ADDRESS_MUST_BE_NON_EMPTY_STRING -> config + * UNSUPPORTED_NETWORK -> Config + * NFT_CONTRACT_ADDRESS_IS_NOT_DEFINED -> Scripts/Config + * NO_ABI -> Config, Actions/Read + * STDERR -> Scripts + * EXECUTOR_CONTRACT_ADDRESS_IS_REQUIRED_FOR_DEVELOPER_NETWORK -> Config + * ACCOUNT_DEPLOY_FAILED_FOR_ADDRESS -> Account + * INVALID_FEES_RATIO -> Actions/Fees + * INVALID_START_DATE -> Actions/Orders + * INVALID_END_DATE -> Actions/Orders + * END_DATE_TOO_FAR -> Actions/Orders + * INVALID_START_AMOUNT -> Actions/Orders + * INVALID_END_AMOUNT -> Actions/Orders + * NO_VALID_VARIANT_FOUND_IN_CAIRO_CUSTOM_ENUM -> Utils + * UNSUPPORTED_STARKNET_NETWORK -> Providers + * NO_ACCOUNT_FOUND -> Account + * CONFIG_NOT_FOUND -> Config/Hooks + * CONFIG_NOT_LOADED -> Config/Hooks + * USECONFIG_WITHIN_ARKPROVIDER -> Config/Hooks + * ACCOUNT_NOT_CONNECTED -> Account + */ diff --git a/packages/core/src/errors/config.ts b/packages/core/src/errors/config.ts new file mode 100644 index 000000000..41213884f --- /dev/null +++ b/packages/core/src/errors/config.ts @@ -0,0 +1,105 @@ +import { BaseError, BaseErrorOptions } from "./base.js"; + +export type InvalidContractAddressErrorType = InvalidContractAddressError & { + name: "InvalidContractAddressError"; +}; +export class InvalidContractAddressError extends BaseError { + override name = "InvalidContractAdressError"; + constructor(name: string, { docsPath, docsSlug }: BaseErrorOptions) { + super(`${name} contract address must be a valid non-empty string`, { + docsPath, + docsSlug + }); + } +} + +export type UnsupportedNetworkErrorType = UnsupportedNetworkError & { + name: "UnsupportedNetworkError"; +}; +export class UnsupportedNetworkError extends BaseError { + override name = "UnsupportedNetworkError"; + constructor(network: string, { docsPath, docsSlug }: BaseErrorOptions) { + super(`Unsupported network: ${network}`, { docsPath, docsSlug }); + } +} + +export type ContractsCheckErrorType = ContractsCheckError & { + name: "ContractsCheckError"; +}; +export class ContractsCheckError extends BaseError { + override name = "ContractsCheckError"; + constructor(stderr: string, { docsPath }: BaseErrorOptions) { + super(stderr, { docsPath }); + } +} + +export type MissingExecutorContractErrorType = MissingExecutorContractError & { + name: "MissingExecutorContractError"; +}; +export class MissingExecutorContractError extends BaseError { + override name = "MissingExecutorContractError"; + constructor({ docsPath, docsSlug }: BaseErrorOptions) { + super("Executor contract address is required for dev network", { + docsPath, + docsSlug + }); + } +} + +export type InvalidVariantCairoCustomEnumErrorType = + InvalidContractAddressError & { + name: "InvalidVariantCairoCustomEnumError"; + }; +export class InvalidVariantCairoCustomEnumError extends BaseError { + override name = "InvalidVariantCairoCustomEnumError"; + constructor({ docsPath }: BaseErrorOptions) { + super("No valid variant found in CairoCustomEnum", { docsPath }); + } +} + +export class UnsupportedStarknetNetworkError extends BaseError { + override name = "UnsupportedStarknetNetworkError"; + constructor( + starknetNetwork: string, + { docsPath, docsSlug }: BaseErrorOptions + ) { + super(`Unsupported starknetNetwork: ${starknetNetwork}`, { + docsPath, + docsSlug + }); + } +} + +export type ConfigNotLoadedType = ConfigNotLoaded & { + name: "ConfigNotLoaded"; +}; +export class ConfigNotFoundError extends BaseError { + override name = "ConfigNotFoundError"; + constructor({ docsPath, docsSlug }: BaseErrorOptions) { + super("Config not found", { docsPath, docsSlug }); + } +} + +export type ConfigNotFoundErrorType = ConfigNotFoundError & { + name: "ConfigNotFoundError"; +}; +export class ConfigNotLoaded extends BaseError { + override name = "ConfigNotLoaded"; + constructor({ docsPath, docsSlug }: BaseErrorOptions) { + super("Config not loaded", { docsPath, docsSlug }); + } +} + +export type UseConfigWithinArkProviderErrorType = + UseConfigWithinArkProviderError & { + name: "UseConfigWithinArkProviderError"; + }; +export class UseConfigWithinArkProviderError extends BaseError { + override name = "UseConfigWithinArkProviderError"; + constructor({ docsPath, docsSlug }: BaseErrorOptions) { + super("useConfig must be used within a ArkProvider", { + docsPath, + docsSlug + }); + } +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d53692761..bb059267d 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,49 +1,81 @@ export { createConfig } from "./createConfig.js"; export { - fetchOrCreateAccount, - createAccount + createAccount, + fetchOrCreateAccount } from "./actions/account/index.js"; export { + cancelCollectionOffer, + cancelOrder, createAuction, + createCollectionOffer, createListing, createOffer, - cancelOrder, fulfillAuction, fulfillListing, - fulfillOffer + fulfillOffer, + type CancelOrderParameters, + type CancelOrderResult, + type CreateAuctionParameters, + type CreateAuctionResult, + type CreateCollectionOfferParameters, + type CreateCollectionOfferResult, + type CreateListingParameters, + type CreateListingResult, + type CreateOfferParameters, + type CreateOfferResult, + type FulfillAuctionParameters, + type FulfillAuctionResult, + type FulfillListingParameters, + type FulfillListingResult, + type FulfillOfferParameters, + type FulfillOfferResult } from "./actions/order/index.js"; export { createBroker } from "./actions/broker/createBroker.js"; export { - getOrderHash, + getArkFees, + getBrokerFees, + getCollectionCreatorFees, + getDefaultCreatorFees, + getFeesAmount, + setArkFees, + setBrokerFees, + setCollectionCreatorFees, + setDefaultCreatorFees +} from "./actions/fees/index.js"; + +export { + getAllowance, getOrder, - getOrderStatus, + getOrderHash, getOrderSigner, - getOrderType, - getAllowance + getOrderStatus, + getOrderType } from "./actions/read/index.js"; export type { AuctionV1, + CancelCollectionOfferInfo, + CancelInfo, + CollectionOfferV1, + FulfillAuctionInfo, ListingV1, OfferV1, - CancelInfo, - RouteType, - FulfillAuctionInfo + RouteType } from "./types/index.js"; export type { Config, - Network, - CreateConfigParameters + CreateConfigParameters, + Network } from "./createConfig.js"; export { - starknetRpcUrls, arkchainRpcUrls, networks, - starknetEthContract + starknetEthContract, + starknetRpcUrls } from "./constants.js"; diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts index 449dd4da9..0ca2c4c79 100644 --- a/packages/core/src/types/index.ts +++ b/packages/core/src/types/index.ts @@ -24,29 +24,37 @@ export type OrderV1 = { }; export type OfferV1 = { - brokerId: string; + brokerAddress: string; tokenAddress: string; - tokenId: bigint; + tokenId?: bigint; currencyAddress?: string; currencyChainId?: constants.StarknetChainId; - startAmount: bigint; + amount: bigint; + startDate?: number; + endDate?: number; +}; + +export type CollectionOfferV1 = { + brokerAddress: string; + tokenAddress: string; + currencyAddress?: string; + currencyChainId?: string; + amount: bigint; startDate?: number; endDate?: number; }; export type ListingV1 = { - brokerId: string; + brokerAddress: string; tokenAddress: string; tokenId: bigint; currencyAddress?: string; currencyChainId?: constants.StarknetChainId; - startAmount: bigint; - startDate?: number; - endDate?: number; + amount: bigint; }; export type AuctionV1 = { - brokerId: string; + brokerAddress: string; tokenAddress: string; tokenId: bigint; currencyAddress?: string; @@ -57,6 +65,11 @@ export type AuctionV1 = { endDate?: number; }; +export type CancelCollectionOfferInfo = { + orderHash: bigint; + tokenAddress: string; +}; + export type CancelInfo = { orderHash: bigint; tokenAddress: string; @@ -78,6 +91,7 @@ export type FulfillInfo = { tokenChainId: constants.StarknetChainId; tokenAddress: string; tokenId: CairoOption; + quantity: Uint256; fulfillBrokerAddress: string; }; @@ -85,11 +99,9 @@ export type BaseFulfillInfo = { orderHash: bigint; tokenAddress: string; tokenId: bigint; - brokerId: string; + brokerAddress: string; }; -export type FulfillOfferInfo = BaseFulfillInfo; - export type FulfillListingInfo = BaseFulfillInfo; export type FulfillAuctionInfo = BaseFulfillInfo & { @@ -105,3 +117,5 @@ export type ApproveErc721Info = { tokenAddress: string; tokenId: bigint; }; + +export type FulfillOfferInfo = BaseFulfillInfo; diff --git a/packages/core/src/types/utils.ts b/packages/core/src/types/utils.ts new file mode 100644 index 000000000..eba2952bd --- /dev/null +++ b/packages/core/src/types/utils.ts @@ -0,0 +1,10 @@ +export type Compute = { [key in keyof type]: type[key] } & unknown; + +export type OneOf< + union extends object, + /// + keys extends KeyofUnion = KeyofUnion +> = union extends infer Item + ? Compute]?: undefined }> + : never; +type KeyofUnion = type extends type ? keyof type : never; diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 50ff28460..7181c73ec 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -4,9 +4,12 @@ import { CallData } from "starknet"; import { OrderV1 } from "../types/index.js"; export const getOrderHashFromOrderV1 = (order: OrderV1) => { - const compiledOrder = CallData.compile({ - order - }); + const compiledOrder = CallData.compile({ order }); const compiletOrderBigIntArray = compiledOrder.map(BigInt); + return starknet.poseidonHashMany(compiletOrderBigIntArray); }; + +export function validateFeesRatio(numerator: number, denominator: number) { + return numerator >= 0 && denominator > 0 && numerator < denominator +} diff --git a/packages/core/src/utils/utils.ts b/packages/core/src/utils/utils.ts new file mode 100644 index 000000000..9c4f70c4b --- /dev/null +++ b/packages/core/src/utils/utils.ts @@ -0,0 +1,3 @@ +import { version } from "../version.js"; + +export const getVersion = () => `@ark-project/core@${version}`; diff --git a/packages/core/tests/cancelAuction.test.ts b/packages/core/tests/cancelAuction.test.ts index 1434ca5d9..8777893e5 100644 --- a/packages/core/tests/cancelAuction.test.ts +++ b/packages/core/tests/cancelAuction.test.ts @@ -1,44 +1,31 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + import { cancelOrder, createAuction } from "../src/actions/order/index.js"; import { getOrderStatus } from "../src/actions/read/index.js"; -import { - accounts, - config, - mintERC721, - STARKNET_NFT_ADDRESS -} from "./utils/index.js"; describe("cancelAuction", () => { it("default", async () => { - const { seller, listingBroker } = accounts; - const tokenId = await mintERC721({ account: seller }); + const { seller, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); - const orderHash = await createAuction(config, { - starknetAccount: seller, - order: { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(1), - endAmount: BigInt(10) - }, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + const { orderHash } = await createAuction(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + startAmount: BigInt(1) }); await cancelOrder(config, { - starknetAccount: seller, - cancelInfo: { - orderHash: orderHash, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + account: seller, + orderHash: orderHash, + tokenAddress, + tokenId }); - const { orderStatus } = await getOrderStatus(config, { - orderHash - }); + const { orderStatus } = await getOrderStatus(config, { orderHash }); expect(orderStatus).toBe("CancelledUser"); }, 50_000); diff --git a/packages/core/tests/cancelCollectionOffer.test.ts b/packages/core/tests/cancelCollectionOffer.test.ts new file mode 100644 index 000000000..6408fbb68 --- /dev/null +++ b/packages/core/tests/cancelCollectionOffer.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + +import { + cancelCollectionOffer, + createCollectionOffer, + getOrderStatus +} from "../src/index.js"; + +describe("cancelCollectionOffer", () => { + it("default", async () => { + const { buyer, listingBroker } = getAccounts(); + const { tokenAddress } = await mintERC721({ account: buyer }); + + const { orderHash } = await createCollectionOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress, + amount: BigInt(10) + }); + + await cancelCollectionOffer(config, { + starknetAccount: buyer, + cancelInfo: { + orderHash, + tokenAddress + } + }); + + const { orderStatus } = await getOrderStatus(config, { orderHash }); + + expect(orderStatus).toEqual("CancelledUser"); + }, 50_000); +}); diff --git a/packages/core/tests/cancelListing.test.ts b/packages/core/tests/cancelListing.test.ts index 747bd4ad8..98081420f 100644 --- a/packages/core/tests/cancelListing.test.ts +++ b/packages/core/tests/cancelListing.test.ts @@ -1,43 +1,34 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + import { cancelOrder, createListing } from "../src/actions/order/index.js"; import { getOrderStatus } from "../src/actions/read/index.js"; -import { - accounts, - config, - mintERC721, - STARKNET_NFT_ADDRESS -} from "./utils/index.js"; describe("cancelListing", () => { it("default", async () => { - const { seller, listingBroker } = accounts; - const tokenId = await mintERC721({ account: seller }); + const { seller, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); - const orderHash = await createListing(config, { - starknetAccount: seller, - order: { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(1) - }, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + const { orderHash } = await createListing(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1) }); await cancelOrder(config, { - starknetAccount: seller, - cancelInfo: { - orderHash, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + account: seller, + orderHash, + tokenAddress, + tokenId }); const { orderStatus } = await getOrderStatus(config, { orderHash }); + expect(orderStatus).toBe("CancelledUser"); }, 50_000); }); diff --git a/packages/core/tests/cancelOffer.test.ts b/packages/core/tests/cancelOffer.test.ts index 9f8131c7e..079c42f08 100644 --- a/packages/core/tests/cancelOffer.test.ts +++ b/packages/core/tests/cancelOffer.test.ts @@ -1,39 +1,28 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC20, mintERC721 } from "@ark-project/test"; + import { cancelOrder, createOffer, getOrderStatus } from "../src/index.js"; -import { - accounts, - config, - mintERC20, - mintERC721, - STARKNET_NFT_ADDRESS -} from "./utils/index.js"; describe("cancelOffer", () => { it("default", async () => { - const { seller, buyer, listingBroker } = accounts; - const tokenId = await mintERC721({ account: seller }); + const { seller, buyer, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); await mintERC20({ account: buyer, amount: 1000 }); - const orderHash = await createOffer(config, { - starknetAccount: buyer, - offer: { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(10) - }, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: BigInt(10) - } + const { orderHash } = await createOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(10) }); await cancelOrder(config, { - starknetAccount: buyer, - cancelInfo: { - orderHash, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + account: buyer, + orderHash, + tokenAddress, + tokenId }); const { orderStatus } = await getOrderStatus(config, { orderHash }); diff --git a/packages/core/tests/createAccount.test.ts b/packages/core/tests/createAccount.test.ts deleted file mode 100644 index 03826393b..000000000 --- a/packages/core/tests/createAccount.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { createAccount } from "../src/actions/account/account.js"; -import { config } from "./utils/index.js"; - -describe("createAccount", () => { - it("default", async () => { - const { arkProvider } = config; - const accountDetails = await createAccount(arkProvider); - - expect(accountDetails).toHaveProperty("address"); - expect(typeof accountDetails.address).toBe("string"); - expect(accountDetails).toHaveProperty("privateKey"); - expect(typeof accountDetails.privateKey).toBe("string"); - expect(accountDetails).toHaveProperty("publicKey"); - expect(typeof accountDetails.publicKey).toBe("string"); - expect(accountDetails).toHaveProperty("account"); - }); -}); diff --git a/packages/core/tests/createAuction.test.ts b/packages/core/tests/createAuction.test.ts index 71ef4f0d6..a4baae370 100644 --- a/packages/core/tests/createAuction.test.ts +++ b/packages/core/tests/createAuction.test.ts @@ -1,30 +1,22 @@ -import { AuctionV1, createAuction, getOrderType } from "../src/index.js"; -import { - accounts, - config, - getTypeFromCairoCustomEnum, - mintERC721, - STARKNET_NFT_ADDRESS -} from "./utils/index.js"; +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + +import { createAuction, getOrderType } from "../src/index.js"; +import { FEE_TOKEN, getTypeFromCairoCustomEnum } from "./utils/index.js"; describe("createAuction", () => { it("default", async () => { - const { seller, listingBroker } = accounts; - const tokenId = await mintERC721({ account: seller }); - - const orderHash = await createAuction(config, { - starknetAccount: seller, - order: { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(1), - endAmount: BigInt(10) - }, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + const { seller, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + + const { orderHash } = await createAuction(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + startAmount: BigInt(1), + endAmount: BigInt(1) }); const orderTypeCairo = await getOrderType(config, { orderHash }); @@ -34,24 +26,17 @@ describe("createAuction", () => { }, 50_000); it("default: with custom currency", async () => { - const { seller, listingBroker } = accounts; - const tokenId = await mintERC721({ account: seller }); - - const orderHash = await createAuction(config, { - starknetAccount: seller, - order: { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(1), - endAmount: BigInt(10), - currencyAddress: - "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d" - }, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + const { seller, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + + const { orderHash } = await createAuction(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + startAmount: BigInt(1), + endAmount: BigInt(10), + currencyAddress: FEE_TOKEN }); const orderTypeCairo = await getOrderType(config, { orderHash }); @@ -61,79 +46,55 @@ describe("createAuction", () => { }, 50_000); it("error: invalid start date", async () => { - const { seller, listingBroker } = accounts; - const tokenId = await mintERC721({ account: seller }); + const { seller, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); const invalidStartDate = Math.floor(Date.now() / 1000 - 30); - const order: AuctionV1 = { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startDate: invalidStartDate, - startAmount: BigInt(1), - endAmount: BigInt(10) - }; - await expect( createAuction(config, { - starknetAccount: seller, - order, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + startDate: invalidStartDate, + startAmount: BigInt(1), + endAmount: BigInt(10) }) ).rejects.toThrow(); }, 50_000); it("error: invalid end date", async () => { - const { seller, listingBroker } = accounts; - const tokenId = await mintERC721({ account: seller }); + const { seller, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); const invalidEndDate = Math.floor(Date.now() / 1000) - 30; - const order: AuctionV1 = { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - endDate: invalidEndDate, - startAmount: BigInt(1), - endAmount: BigInt(10) - }; - await expect( createAuction(config, { - starknetAccount: seller, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - }, - order + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + endDate: invalidEndDate, + startAmount: BigInt(1), + endAmount: BigInt(10) }) ).rejects.toThrow(); }, 50_000); it("error: invalid end amount", async () => { - const { seller, listingBroker } = accounts; - const tokenId = await mintERC721({ account: seller }); - - const order: AuctionV1 = { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(1), - endAmount: BigInt(0) - }; + const { seller, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); await expect( createAuction(config, { - starknetAccount: seller, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - }, - order + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + startAmount: BigInt(2), + endAmount: BigInt(1) }) ).rejects.toThrow(); }, 50_000); diff --git a/packages/core/tests/createCollectionOffer.test.ts b/packages/core/tests/createCollectionOffer.test.ts new file mode 100644 index 000000000..3f67f59c5 --- /dev/null +++ b/packages/core/tests/createCollectionOffer.test.ts @@ -0,0 +1,81 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC20 } from "@ark-project/test"; + +import { + createCollectionOffer, + getOrderStatus, + getOrderType +} from "../src/index.js"; +import { + getTypeFromCairoCustomEnum, + STARKNET_NFT_ADDRESS +} from "./utils/index.js"; + +describe("createCollectionOffer", () => { + it("default", async () => { + const { buyer, listingBroker } = getAccounts(); + await mintERC20({ account: buyer, amount: 10000000 }); + + const { orderHash } = await createCollectionOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress: STARKNET_NFT_ADDRESS, + amount: BigInt(10) + }); + const orderTypeCairo = await getOrderType(config, { orderHash }); + const orderType = getTypeFromCairoCustomEnum(orderTypeCairo.orderType); + const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { + orderHash + }); + + expect(orderType).toBe("COLLECTION_OFFER"); + expect(orderStatusAfter).toBe("Open"); + }, 50_000); + + it("error: invalid start date", async () => { + const { buyer, listingBroker } = getAccounts(); + await mintERC20({ account: buyer, amount: 10000000 }); + + await expect( + createCollectionOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress: STARKNET_NFT_ADDRESS, + amount: BigInt(10), + startDate: Math.floor(Date.now() / 1000) - 1000 + }) + ).rejects.toThrow(); + }, 50_000); + + it("error: invalid start date / end date", async () => { + const { buyer, listingBroker } = getAccounts(); + await mintERC20({ account: buyer, amount: 10000000 }); + + await expect( + createCollectionOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress: STARKNET_NFT_ADDRESS, + amount: BigInt(10), + startDate: Math.floor(Date.now() / 1000) + 1000, + endDate: Math.floor(Date.now() / 1000) + 500 + }) + ).rejects.toThrow(); + }, 50_000); + + it("error: invalid end date", async () => { + const { buyer, listingBroker } = getAccounts(); + await mintERC20({ account: buyer, amount: 10000000 }); + + await expect( + createCollectionOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress: STARKNET_NFT_ADDRESS, + amount: BigInt(10), + endDate: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30 + 1 + }) + ).rejects.toThrow(); + }, 50_000); +}); diff --git a/packages/core/tests/createConfig.test.ts b/packages/core/tests/createConfig.test.ts index a67e09932..da2c2241c 100644 --- a/packages/core/tests/createConfig.test.ts +++ b/packages/core/tests/createConfig.test.ts @@ -1,10 +1,11 @@ +import { describe, expect } from "vitest"; + import { createConfig, networks } from "../src/index.js"; describe("createconfig", () => { test("default", async () => { const config = createConfig({ - starknetNetwork: networks.mainnet, - arkchainNetwork: networks.mainnet + starknetNetwork: networks.mainnet }); expect(config).toBeDefined(); @@ -13,19 +14,7 @@ describe("createconfig", () => { test("error: missing dev starknetExecutorContract", async () => { expect(() => { createConfig({ - starknetNetwork: networks.dev, - arkchainNetwork: networks.dev, - arkchainOrderbookContract: "0x" - }); - }).toThrow(); - }); - - test("error: missing dev arkchainOrderbookContract", async () => { - expect(() => { - createConfig({ - starknetNetwork: networks.dev, - arkchainNetwork: networks.dev, - starknetExecutorContract: "0x" + starknetNetwork: networks.dev }); }).toThrow(); }); diff --git a/packages/core/tests/createListing.test.ts b/packages/core/tests/createListing.test.ts index ae34819dd..fcdb7b6fb 100644 --- a/packages/core/tests/createListing.test.ts +++ b/packages/core/tests/createListing.test.ts @@ -1,29 +1,21 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + import { createListing } from "../src/actions/order/index.js"; import { getOrderStatus } from "../src/actions/read/index.js"; -import { - accounts, - config, - mintERC721, - STARKNET_NFT_ADDRESS -} from "./utils/index.js"; describe("createListing", () => { it("default", async () => { - const { seller } = accounts; - const tokenId = await mintERC721({ account: seller }); - - const orderHash = await createListing(config, { - starknetAccount: seller, - order: { - brokerId: accounts.listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(1) - }, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + const { listingBroker, seller } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + + const { orderHash } = await createListing(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1) }); const { orderStatus } = await getOrderStatus(config, { orderHash }); @@ -31,23 +23,15 @@ describe("createListing", () => { }, 50_000); it("default: with custom currency", async () => { - const { seller } = accounts; - const tokenId = await mintERC721({ account: seller }); - - const orderHash = await createListing(config, { - starknetAccount: seller, - order: { - brokerId: accounts.listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(1), - currencyAddress: - "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d" - }, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + const { seller, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + + const { orderHash } = await createListing(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1) }); const { orderStatus } = await getOrderStatus(config, { orderHash }); diff --git a/packages/core/tests/createOffer.test.ts b/packages/core/tests/createOffer.test.ts index 2de1df00e..af3709280 100644 --- a/packages/core/tests/createOffer.test.ts +++ b/packages/core/tests/createOffer.test.ts @@ -1,34 +1,23 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC20, mintERC721 } from "@ark-project/test"; + import { createOffer, getOrderStatus } from "../src/index.js"; -import { - accounts, - config, - mintERC20, - mintERC721, - STARKNET_NFT_ADDRESS -} from "./utils/index.js"; describe("createOffer", () => { it("default", async () => { - const { seller, buyer } = accounts; - const tokenId = await mintERC721({ account: seller }); - await mintERC20({ account: buyer, amount: 1000 }); + const { seller, buyer, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + await mintERC20({ account: buyer, amount: 10000000 }); - const orderHash = await createOffer(config, { - starknetAccount: buyer, - offer: { - brokerId: accounts.listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(10) - }, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: BigInt(10) - } + const { orderHash } = await createOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(10) }); - await new Promise((resolve) => setTimeout(resolve, 5_000)); - const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { orderHash }); @@ -58,8 +47,6 @@ describe("createOffer", () => { // } // }); - // await new Promise((resolve) => setTimeout(resolve, 5_000)); - // const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { // orderHash // }); @@ -68,25 +55,18 @@ describe("createOffer", () => { // }, 50_000); it("error: invalid currency address", async () => { - const { seller, buyer } = accounts; - const tokenId = await mintERC721({ account: seller }); + const { seller, listingBroker, buyer } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); await mintERC20({ account: buyer, amount: 1 }); await expect( createOffer(config, { - starknetAccount: buyer, - offer: { - brokerId: accounts.listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(10), - currencyAddress: - "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d" - }, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: BigInt(10) - } + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1), + currencyAddress: "0x0" }) ).rejects.toThrow(); }, 50_000); diff --git a/packages/core/tests/fulfillAuction.test.ts b/packages/core/tests/fulfillAuction.test.ts index 3de48f984..d62643e56 100644 --- a/packages/core/tests/fulfillAuction.test.ts +++ b/packages/core/tests/fulfillAuction.test.ts @@ -1,72 +1,58 @@ -import { fulfillAuction } from "../src/actions/order/fulfillAuction.js"; -import { createAuction, createOffer } from "../src/actions/order/index.js"; -import { getOrderStatus } from "../src/actions/read/index.js"; +import { describe, expect, it } from "vitest"; + import { - accounts, config, + getAccounts, getBalance, mintERC20, - mintERC721, - STARKNET_NFT_ADDRESS -} from "./utils/index.js"; + mintERC721 +} from "@ark-project/test"; + +import { fulfillAuction } from "../src/actions/order/fulfillAuction.js"; +import { createAuction, createOffer } from "../src/actions/order/index.js"; +import { getOrderStatus } from "../src/actions/read/index.js"; describe("fulfillAuction", () => { it("default", async () => { - const { seller, buyer } = accounts; - const tokenId = await mintERC721({ account: seller }); + const { seller, buyer, saleBroker, listingBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); const initialSellerBalance = await getBalance({ account: seller }); + const amount = BigInt(1000); await mintERC20({ account: buyer, amount: 5000 }); - const orderHash = await createAuction(config, { - starknetAccount: seller, - order: { - brokerId: accounts.listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: BigInt(1000), - endAmount: BigInt(5000) - }, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + const { orderHash } = await createAuction(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + startAmount: BigInt(1000) }); - const offerAmount = BigInt(1000); - const offerOrderHash = await createOffer(config, { - starknetAccount: buyer, - offer: { - brokerId: accounts.listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: offerAmount - }, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: offerAmount - } + const { orderHash: offerOrderHash } = await createOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount }); await fulfillAuction(config, { - starknetAccount: seller, - fulfillAuctionInfo: { - orderHash, - relatedOrderHash: offerOrderHash, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - brokerId: accounts.listingBroker.address - } + account: buyer, + brokerAddress: saleBroker.address, + orderHash, + relatedOrderHash: offerOrderHash, + tokenAddress, + tokenId, + quantity: BigInt(1), }); - await new Promise((resolve) => setTimeout(resolve, 4_000)); - const { orderStatus } = await getOrderStatus(config, { orderHash }); const sellerBalance = await getBalance({ account: seller }); - const fees = (BigInt(offerAmount) * BigInt(0)) / BigInt(100); - const profit = BigInt(offerAmount) - fees; + const fees = (BigInt(amount) * BigInt(1)) / BigInt(100); + const profit = BigInt(amount) - fees; expect(orderStatus).toBe("Executed"); expect(sellerBalance).toEqual(initialSellerBalance + profit); diff --git a/packages/core/tests/fulfillListing.test.ts b/packages/core/tests/fulfillListing.test.ts index 699a60355..d142e3384 100644 --- a/packages/core/tests/fulfillListing.test.ts +++ b/packages/core/tests/fulfillListing.test.ts @@ -1,48 +1,34 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + import { getOrderStatus } from "../src/actions/read/index.js"; import { createListing, fulfillListing } from "../src/index.js"; -import { - accounts, - config, - mintERC721, - STARKNET_NFT_ADDRESS -} from "./utils/index.js"; describe("fulfillOffer", () => { it("default", async () => { - const { seller, buyer, listingBroker, saleBroker } = accounts; - const tokenId = await mintERC721({ account: seller }); + const { seller, buyer, listingBroker, saleBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); const startAmount = BigInt(1); - const orderHash = await createListing(config, { - starknetAccount: seller, - order: { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount - }, - approveInfo: { - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId - } + const { orderHash } = await createListing(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: startAmount }); await fulfillListing(config, { - starknetAccount: buyer, - fulfillListingInfo: { - orderHash, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - brokerId: saleBroker.address - }, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: startAmount - } + account: buyer, + brokerAddress: saleBroker.address, + orderHash, + tokenAddress, + tokenId, + quantity: BigInt(1), + amount: startAmount }); - await new Promise((resolve) => setTimeout(resolve, 4_000)); - const { orderStatus } = await getOrderStatus(config, { orderHash }); diff --git a/packages/core/tests/fulfillOffer.test.ts b/packages/core/tests/fulfillOffer.test.ts index 9e78c1fed..570b779bc 100644 --- a/packages/core/tests/fulfillOffer.test.ts +++ b/packages/core/tests/fulfillOffer.test.ts @@ -1,123 +1,85 @@ +import { describe, expect, it } from "vitest"; + import { - createOffer, - fulfillOffer, - getOrderStatus, - OfferV1 -} from "../src/index.js"; -import { - accounts, config, + getAccounts, getBalance, mintERC20, - mintERC721, - STARKNET_NFT_ADDRESS -} from "./utils/index.js"; + mintERC721 +} from "@ark-project/test"; + +import { createOffer, fulfillOffer, getOrderStatus } from "../src/index.js"; describe("fulfillOffer", () => { it("default", async function () { - const { seller, buyer, listingBroker, saleBroker } = accounts; + const { seller, buyer, listingBroker, saleBroker } = getAccounts(); + const amount = BigInt(1000); await mintERC20({ account: buyer, amount: 100000 }); - const tokenId = await mintERC721({ account: seller }); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); const initialSellerBalance = await getBalance({ account: seller }); - const offer: OfferV1 = { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, + const { orderHash } = await createOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress, tokenId, - startAmount: BigInt(10) - }; - - const orderHash = await createOffer(config, { - starknetAccount: buyer, - offer, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: offer.startAmount - } + amount }); await fulfillOffer(config, { - starknetAccount: seller, - fulfillOfferInfo: { - orderHash, - tokenAddress: offer.tokenAddress, - tokenId: offer.tokenId, - brokerId: saleBroker.address - }, - approveInfo: { - tokenAddress: offer.tokenAddress, - tokenId: offer.tokenId - } + account: seller, + brokerAddress: saleBroker.address, + orderHash, + tokenAddress, + tokenId, + quantity: BigInt(1), }); - await new Promise((resolve) => setTimeout(resolve, 4_000)); - const { orderStatus: orderStatusFulfilled } = await getOrderStatus(config, { orderHash }); - const balance = await getBalance({ account: seller }); - const fees = - (BigInt(offer.startAmount) * - (BigInt(100) + BigInt(100) + BigInt(100) + BigInt(100))) / - BigInt(10000); - const profit = BigInt(offer.startAmount) - fees; + const sellerBalance = await getBalance({ account: seller }); + const fees = (BigInt(amount) * BigInt(1)) / BigInt(100); + const profit = BigInt(amount) - fees; expect(orderStatusFulfilled).toBe("Executed"); - expect(balance).toEqual(initialSellerBalance + profit); + expect(sellerBalance).toEqual(initialSellerBalance + profit); }, 50_000); it("default: with custom fees", async function () { - const { seller, buyer, listingBroker, saleBroker } = accounts; - + const { seller, buyer, listingBroker, saleBroker } = getAccounts(); + const amount = BigInt(1000); await mintERC20({ account: buyer, amount: 100000 }); - const tokenId = await mintERC721({ account: seller }); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); const initialSellerBalance = await getBalance({ account: seller }); - const offer: OfferV1 = { - brokerId: listingBroker.address, - tokenAddress: STARKNET_NFT_ADDRESS, + const { orderHash } = await createOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress, tokenId, - startAmount: BigInt(10) - }; - - const orderHash = await createOffer(config, { - starknetAccount: buyer, - offer, - approveInfo: { - currencyAddress: config.starknetCurrencyContract, - amount: offer.startAmount - } + amount }); await fulfillOffer(config, { - starknetAccount: seller, - fulfillOfferInfo: { - orderHash, - tokenAddress: offer.tokenAddress, - tokenId: offer.tokenId, - brokerId: saleBroker.address - }, - approveInfo: { - tokenAddress: offer.tokenAddress, - tokenId: offer.tokenId - } + account: seller, + orderHash, + tokenAddress, + tokenId, + quantity: BigInt(1), + brokerAddress: saleBroker.address }); - await new Promise((resolve) => setTimeout(resolve, 4_000)); - const { orderStatus: orderStatusFulfilled } = await getOrderStatus(config, { orderHash }); - const balance = await getBalance({ account: seller }); - const fees = - (BigInt(offer.startAmount) * - (BigInt(100) + BigInt(100) + BigInt(100) + BigInt(100))) / - BigInt(10000); - const profit = BigInt(offer.startAmount) - fees; + const sellerBalance = await getBalance({ account: seller }); + const fees = (BigInt(amount) * BigInt(1)) / BigInt(100); + const profit = BigInt(amount) - fees; expect(orderStatusFulfilled).toBe("Executed"); - expect(balance).toEqual(initialSellerBalance + profit); + expect(sellerBalance).toEqual(initialSellerBalance + profit); }, 50_000); }); diff --git a/packages/core/tests/getArkFees.test.ts b/packages/core/tests/getArkFees.test.ts new file mode 100644 index 000000000..9f1cb5382 --- /dev/null +++ b/packages/core/tests/getArkFees.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from "vitest"; + +import { config } from "@ark-project/test"; + +import { getArkFees } from "../src/index.js"; + +describe("getArkFees", () => { + it("default", async () => { + const fees = await getArkFees(config); + + expect(fees).toMatchObject({ + formatted: expect.any(String), + denominator: expect.any(BigInt), + numerator: expect.any(BigInt) + }); + }, 50_000); +}); diff --git a/packages/core/tests/getBrokerFees.test.ts b/packages/core/tests/getBrokerFees.test.ts new file mode 100644 index 000000000..e26fe4ab3 --- /dev/null +++ b/packages/core/tests/getBrokerFees.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts } from "@ark-project/test"; + +import { getBrokerFees } from "../src/index.js"; + +describe("getBrokerFees", () => { + it("default", async () => { + const { listingBroker } = getAccounts(); + const fees = await getBrokerFees(config, listingBroker.address); + + expect(fees).toMatchObject({ + formatted: expect.any(String), + denominator: expect.any(BigInt), + numerator: expect.any(BigInt) + }); + }, 50_000); +}); diff --git a/packages/core/tests/getCollectionCreatorFees.test.ts b/packages/core/tests/getCollectionCreatorFees.test.ts new file mode 100644 index 000000000..4113faf8b --- /dev/null +++ b/packages/core/tests/getCollectionCreatorFees.test.ts @@ -0,0 +1,24 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + +import { getCollectionCreatorFees } from "../src/index.js"; + +describe("getCollectionCreatorFees", () => { + it("default", async () => { + const { seller } = getAccounts(); + const { tokenAddress } = await mintERC721({ account: seller }); + + const { creator, fees } = await getCollectionCreatorFees( + config, + tokenAddress + ); + + expect(creator).toBeDefined(); + expect(fees).toMatchObject({ + formatted: expect.any(String), + denominator: expect.any(BigInt), + numerator: expect.any(BigInt) + }); + }, 50_000); +}); diff --git a/packages/core/tests/getDefaultCreatorFees.test.ts b/packages/core/tests/getDefaultCreatorFees.test.ts new file mode 100644 index 000000000..2bfef73b0 --- /dev/null +++ b/packages/core/tests/getDefaultCreatorFees.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from "vitest"; + +import { config } from "@ark-project/test"; + +import { getDefaultCreatorFees } from "../src/index.js"; + +describe("getDefaultCreatorFees", () => { + it("default", async () => { + const { creator, fees } = await getDefaultCreatorFees(config); + + expect(creator).toBeDefined(); + expect(fees).toMatchObject({ + formatted: expect.any(String), + denominator: expect.any(BigInt), + numerator: expect.any(BigInt) + }); + }, 50_000); +}); diff --git a/packages/core/tests/getFeesAmount.test.ts b/packages/core/tests/getFeesAmount.test.ts new file mode 100644 index 000000000..f7735a31b --- /dev/null +++ b/packages/core/tests/getFeesAmount.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + +import { getFeesAmount } from "../src/index.js"; + +describe("getFeesAmount", () => { + it("default", async () => { + const { seller, listingBroker, saleBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + + const fees = await getFeesAmount(config, { + fulfillBroker: saleBroker.address, + listingBroker: listingBroker.address, + nftAddress: tokenAddress, + nftTokenId: tokenId, + paymentAmount: BigInt(10000) + }); + + expect(fees).toMatchObject({ + listingBroker: expect.any(BigInt), + fulfillBroker: expect.any(BigInt), + creator: expect.any(BigInt), + ark: expect.any(BigInt) + }); + }, 50_000); +}); diff --git a/packages/core/tests/setArkFees.test.ts b/packages/core/tests/setArkFees.test.ts new file mode 100644 index 000000000..a59cb29df --- /dev/null +++ b/packages/core/tests/setArkFees.test.ts @@ -0,0 +1,40 @@ +import { Account } from "starknet"; +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + +import { getFeesAmount, setArkFees } from "../src/index.js"; + +describe("setArkFees", () => { + it("default", async () => { + const { seller, listingBroker, saleBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + const amount = BigInt(10000); + const numerator = 1; + const denominator = 100; + + const fees = await getFeesAmount(config, { + fulfillBroker: saleBroker.address, + listingBroker: listingBroker.address, + nftAddress: tokenAddress, + nftTokenId: tokenId, + paymentAmount: amount + }); + + expect(fees.ark).toBe((amount * BigInt(numerator)) / BigInt(denominator)); + }, 50_000); + + it("error: invalid fees ratio", async () => { + const { admin } = getAccounts(); + const numerator = 100; + const denominator = 1; + + await expect( + setArkFees(config, { + account: admin as Account, + numerator, + denominator + }) + ).rejects.toThrow(); + }, 50_000); +}); diff --git a/packages/core/tests/setBrokerFees.test.ts b/packages/core/tests/setBrokerFees.test.ts new file mode 100644 index 000000000..2b8f9f167 --- /dev/null +++ b/packages/core/tests/setBrokerFees.test.ts @@ -0,0 +1,57 @@ +import { Account } from "starknet"; +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + +import { NoABIError } from "../src/errors/actions.js"; +import { getFeesAmount, setBrokerFees } from "../src/index.js"; + +describe("setBrokerFees", () => { + it("default", async () => { + const { seller, listingBroker, saleBroker } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + const amount = BigInt(10000); + const numerator = 1; + const denominator = 100; + + const { abi } = await config.starknetProvider.getClassAt( + config.starknetExecutorContract + ); + + if (abi === undefined) { + throw new NoABIError({ docsPath: "" }); + } + + await setBrokerFees(config, { + brokerAccount: listingBroker as Account, + numerator, + denominator + }); + + const fees = await getFeesAmount(config, { + fulfillBroker: saleBroker.address, + listingBroker: listingBroker.address, + nftAddress: tokenAddress, + nftTokenId: tokenId, + paymentAmount: amount + }); + + expect(fees.listingBroker).toBe( + (amount * BigInt(numerator)) / BigInt(denominator) + ); + }, 50_000); + + it("error: invalid fees ratio", async () => { + const { listingBroker } = getAccounts(); + const numerator = 100; + const denominator = 1; + + await expect( + setBrokerFees(config, { + brokerAccount: listingBroker as Account, + numerator, + denominator + }) + ).rejects.toThrow(); + }, 50_000); +}); diff --git a/packages/core/tests/setCollectionCreatorFees.test.ts b/packages/core/tests/setCollectionCreatorFees.test.ts new file mode 100644 index 000000000..6569a8e1d --- /dev/null +++ b/packages/core/tests/setCollectionCreatorFees.test.ts @@ -0,0 +1,59 @@ +import { Account } from "starknet"; +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + +import { getFeesAmount, setCollectionCreatorFees } from "../src/index.js"; + +describe("setCollectionCreatorFees", () => { + it("default", async () => { + const { + admin, + seller, + listingBroker, + saleBroker, + arkSetbyAdminCollectionReceiver + } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + const amount = BigInt(10000); + const numerator = 1; + const denominator = 100; + + await setCollectionCreatorFees(config, { + account: admin as Account, + tokenAddress, + receiver: arkSetbyAdminCollectionReceiver.address, + numerator, + denominator + }); + + const fees = await getFeesAmount(config, { + fulfillBroker: saleBroker.address, + listingBroker: listingBroker.address, + nftAddress: tokenAddress, + nftTokenId: tokenId, + paymentAmount: amount + }); + + expect(fees.creator).toBe( + (amount * BigInt(numerator)) / BigInt(denominator) + ); + }, 50_000); + + it("error: invalid fees ratio", async () => { + const { admin, seller, arkSetbyAdminCollectionReceiver } = getAccounts(); + const { tokenAddress } = await mintERC721({ account: seller }); + const numerator = 100; + const denominator = 1; + + await expect( + setCollectionCreatorFees(config, { + account: admin as Account, + tokenAddress, + receiver: arkSetbyAdminCollectionReceiver.address, + numerator, + denominator + }) + ).rejects.toThrow(); + }, 50_000); +}); diff --git a/packages/core/tests/setDefaultCreatorFees.test.ts b/packages/core/tests/setDefaultCreatorFees.test.ts new file mode 100644 index 000000000..802f3d108 --- /dev/null +++ b/packages/core/tests/setDefaultCreatorFees.test.ts @@ -0,0 +1,56 @@ +import { Account } from "starknet"; +import { describe, expect, it } from "vitest"; + +import { config, getAccounts, mintERC721 } from "@ark-project/test"; + +import { getFeesAmount, setDefaultCreatorFees } from "../src/index.js"; + +describe("setDefaultCreatorFees", () => { + it("default", async () => { + const { + admin, + seller, + listingBroker, + saleBroker, + arkSetbyAdminCollectionReceiver + } = getAccounts(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + const amount = BigInt(10000); + const numerator = 1; + const denominator = 100; + + await setDefaultCreatorFees(config, { + account: admin as Account, + receiver: arkSetbyAdminCollectionReceiver.address, + numerator, + denominator + }); + + const fees = await getFeesAmount(config, { + fulfillBroker: saleBroker.address, + listingBroker: listingBroker.address, + nftAddress: tokenAddress, + nftTokenId: tokenId, + paymentAmount: amount + }); + + expect(fees.creator).toBe( + (amount * BigInt(numerator)) / BigInt(denominator) + ); + }, 50_000); + + it("error: invalid fees ratio", async () => { + const { admin, arkSetbyAdminCollectionReceiver } = getAccounts(); + const numerator = 100; + const denominator = 1; + + await expect( + setDefaultCreatorFees(config, { + account: admin as Account, + receiver: arkSetbyAdminCollectionReceiver.address, + numerator, + denominator + }) + ).rejects.toThrow(); + }, 50_000); +}); diff --git a/packages/core/tests/setup.ts b/packages/core/tests/setup.ts index 0c422eddf..c0e0a49e2 100644 --- a/packages/core/tests/setup.ts +++ b/packages/core/tests/setup.ts @@ -1,3 +1,30 @@ import * as dotenv from "dotenv"; +import { Account } from "starknet"; +import { beforeAll } from "vitest"; -dotenv.config({ path: "../../.env" }); +import { config, getAccounts } from "@ark-project/test"; + +import { setArkFees } from "../src/index.js"; + +dotenv.config({ path: `${__dirname}/../../../.env.test` }); + +async function startMocking() { + const numerator = 1; + const denominator = 100; + try { + const { admin } = getAccounts(); + await setArkFees(config, { + account: admin as Account, + numerator, + denominator + }); + } catch (error) { + console.error("Error setting Ark fees:", error); + } +} + +beforeAll(async () => { + await startMocking(); +}); + +export {}; diff --git a/packages/core/tests/utils/index.ts b/packages/core/tests/utils/index.ts index 75f1d25ac..19dd3f2c8 100644 --- a/packages/core/tests/utils/index.ts +++ b/packages/core/tests/utils/index.ts @@ -1,32 +1,16 @@ -import { - Account, - cairo, - CairoCustomEnum, - Call, - CallData, - Contract, - ProviderInterface -} from "starknet"; +import { CairoCustomEnum } from "starknet"; import contracts from "../../../../contracts.dev.json"; -import { Config, createConfig } from "../../src/createConfig.js"; -import { createBroker } from "../../src/index.js"; +import { InvalidVariantCairoCustomEnumError } from "../../src/errors/config.js"; type VariantKey = "Listing" | "Auction" | "Offer" | "CollectionOffer"; export const STARKNET_NFT_ADDRESS = contracts.nftContract; -export const config = createConfig({ - starknetNetwork: "dev", - starknetExecutorContract: contracts.executor, - starknetCurrencyContract: contracts.eth, - arkchainNetwork: "dev", - arkchainOrderbookContract: contracts.orderbook -}); +export const FEE_TOKEN = + "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"; -export function generateRandomTokenId(): number { - return Math.floor(Math.random() * 10000) + 1; -} +export { contracts }; export function getTypeFromCairoCustomEnum(cairoCustomEnum: CairoCustomEnum) { const keyMap = { @@ -42,341 +26,5 @@ export function getTypeFromCairoCustomEnum(cairoCustomEnum: CairoCustomEnum) { } } - throw new Error("No valid variant found in CairoCustomEnum"); -} - -export const whitelistBroker = async ( - config: Config, - adminAccount: Account, - brokerId: string -) => { - const { abi: orderbookAbi } = await config.arkProvider.getClassAt( - config.arkchainOrderbookContract - ); - - if (orderbookAbi === undefined) { - throw new Error("no abi."); - } - - const whitelist_hash_calldata = CallData.compile({ - broker_id: brokerId - }); - - const result = await adminAccount.execute({ - contractAddress: config.arkchainOrderbookContract, - entrypoint: "whitelist_broker", - calldata: whitelist_hash_calldata - }); - - await config.arkProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); - - return result; -}; - -export const mintERC20 = async ({ - account, - amount = 1000 -}: { - account: Account; - amount: number; -}) => { - const { abi } = await config.starknetProvider.getClassAt( - config.starknetCurrencyContract - ); - - if (!abi) { - throw new Error("no abi."); - } - - const mintERC20Call: Call = { - contractAddress: config.starknetCurrencyContract, - entrypoint: "mint", - calldata: CallData.compile([account.address, cairo.uint256(amount)]) - }; - - const result = await account.execute(mintERC20Call, [abi]); - - await config.starknetProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 1000 - }); - - return result.transaction_hash; -}; - -export async function mintERC721({ account }: { account: Account }) { - const { abi } = await config.starknetProvider.getClassAt( - contracts.nftContract - ); - - if (!abi) { - throw new Error("no abi."); - } - - const contract = new Contract( - abi, - contracts.nftContract, - config.starknetProvider - ); - const tokenId: bigint = await contract.get_current_token_id(); - - const mintCall: Call = { - contractAddress: contracts.nftContract, - entrypoint: "mint", - calldata: CallData.compile({ - recipient: account.address, - token_uri: `https://api.everai.xyz/m/1` - }) - }; - - const { transaction_hash } = await account.execute(mintCall, [abi]); - - await config.starknetProvider.waitForTransaction(transaction_hash, { - retryInterval: 1000 - }); - - return tokenId; -} - -export const getCurrentTokenId = async ( - config: Config, - nftContractAddress: string -) => { - const { abi } = await config.starknetProvider.getClassAt(nftContractAddress); - - if (!abi) { - throw new Error("no abi."); - } - - const nftContract = new Contract( - abi, - nftContractAddress, - config.starknetProvider - ); - - const token_id = await nftContract.get_current_token_id(); - // we need to subtract 1 because the contract returns the next token id - return token_id - BigInt(1); -}; - -export const getBalance = async ({ account }: { account: Account }) => { - const { abi } = await config.starknetProvider.getClassAt( - config.starknetCurrencyContract - ); - - if (!abi) { - throw new Error("no abi."); - } - - const contract = new Contract( - abi, - config.starknetCurrencyContract, - config.starknetProvider - ); - - const balance: bigint = await contract.balanceOf(account.address); - - return balance; -}; - -export const setArkFees = async ( - config: Config, - deployerAccount: Account, - fees: number -) => { - const { abi } = await config.starknetProvider.getClassAt( - config.starknetExecutorContract - ); - - if (!abi) { - throw new Error("no abi."); - } - - const executorContract = new Contract( - abi, - config.starknetExecutorContract, - config.starknetProvider - ); - - executorContract.connect(deployerAccount); - - const response = await executorContract.set_ark_fees({ - numerator: cairo.uint256(fees), - denominator: cairo.uint256(10000) - }); - - await config.starknetProvider.waitForTransaction(response.transaction_hash); -}; - -export const setBrokerFees = async ( - config: Config, - brokerAccount: Account, - fees: number -) => { - await createBroker(config, { - brokenAccount: brokerAccount, - numerator: fees, - denominator: 10000 - }); -}; - -function fetchAccount( - provider: ProviderInterface, - address: string, - privateKey: string -): Account { - return new Account(provider, address, privateKey); -} - -export const accounts = { - arkDefaultFeesReceiver: fetchAccount( - config.starknetProvider, - process.env.STARKNET_ARK_RECEIVER_ADDRESS!, - process.env.STARKNET_ARK_RECEIVER_PRIVATE_KEY! - ), - arkSetbyAdminCollectionReceiver: fetchAccount( - config.starknetProvider, - process.env.STARKNET_ARK_COLLECTION_RECEIVER_ADDRESS!, - process.env.STARKNET_ARK_COLLECTION_RECEIVER_PRIVATE_KEY! - ), - arkCollection2981Receiver: fetchAccount( - config.starknetProvider, - process.env.STARKNET_ARK_COLLECTION_2981_RECEIVER_ADDRESS!, - process.env.STARKNET_ARK_COLLECTION_2981_RECEIVER_PRIVATE_KEY! - ), - admin: fetchAccount( - config.starknetProvider, - process.env.STARKNET_ADMIN_ADDRESS_DEV!, - process.env.STARKNET_ADMIN_PRIVATE_KEY_DEV! - ), - listingBroker: fetchAccount( - config.starknetProvider, - process.env.STARKNET_LISTING_BROKER_ACCOUNT_ADDRESS!, - process.env.STARKNET_LISTING_BROKER_ACCOUNT_PRIVATE_KEY! - ), - saleBroker: fetchAccount( - config.starknetProvider, - process.env.STARKNET_SALE_BROKER_ACCOUNT_ADDRESS!, - process.env.STARKNET_SALE_BROKER_ACCOUNT_PRIVATE_KEY! - ), - offerer: fetchAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS!, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY! - ), - fulfiller: fetchAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT2_ADDRESS!, - process.env.STARKNET_ACCOUNT2_PRIVATE_KEY! - ), - seller: fetchAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS!, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY! - ), - buyer: fetchAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT2_ADDRESS!, - process.env.STARKNET_ACCOUNT2_PRIVATE_KEY! - ) -}; - -export const setCollectionCreatorFees = async ( - config: Config, - adminAccount: Account, - arkCollectionReceiver: string, - fees: number, - nftAddress: string -) => { - const { abi } = await config.starknetProvider.getClassAt( - config.starknetExecutorContract - ); - if (abi === undefined) { - throw new Error("no abi."); - } - - const executorContract = new Contract( - abi, - config.starknetExecutorContract, - config.starknetProvider - ); - executorContract.connect(adminAccount); - const response = await executorContract.set_collection_creator_fees( - nftAddress, - arkCollectionReceiver, - { - numerator: cairo.uint256(fees), - denominator: cairo.uint256(10000) - } - ); - await config.starknetProvider.waitForTransaction(response.transaction_hash); -}; - -export const setDefaultCreatorFees = async ( - config: Config, - deployerAccount: Account, - arkReceiver: string, - fees: number -) => { - const { abi } = await config.starknetProvider.getClassAt( - config.starknetExecutorContract - ); - if (abi === undefined) { - throw new Error("no abi."); - } - - const executorContract = new Contract( - abi, - config.starknetExecutorContract, - config.starknetProvider - ); - executorContract.connect(deployerAccount); - const response = await executorContract.set_default_creator_fees( - arkReceiver, - { - numerator: cairo.uint256(fees), - denominator: cairo.uint256(10000) - } - ); - - await config.starknetProvider.waitForTransaction(response.transaction_hash); -}; - -export async function setupFees(config: Config) { - await setArkFees(config, accounts.admin, 100); - await setBrokerFees(config, accounts.listingBroker, 100); - await setBrokerFees(config, accounts.saleBroker, 100); - await setDefaultCreatorFees( - config, - accounts.admin, - accounts.arkDefaultFeesReceiver.address, - 100 - ); - await setCollectionCreatorFees( - config, - accounts.admin, - accounts.arkSetbyAdminCollectionReceiver.address, - 100, - contracts.nftContractFixedFees - ); -} - -export async function resetFees(config: Config) { - await setArkFees(config, accounts.admin, 0); - await setBrokerFees(config, accounts.listingBroker, 0); - await setBrokerFees(config, accounts.saleBroker, 0); - await setDefaultCreatorFees( - config, - accounts.admin, - accounts.arkDefaultFeesReceiver.address, - 0 - ); - await setCollectionCreatorFees( - config, - accounts.admin, - accounts.arkSetbyAdminCollectionReceiver.address, - 0, - contracts.nftContractFixedFees - ); + throw new InvalidVariantCairoCustomEnumError({ docsPath: "" }); } diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts new file mode 100644 index 000000000..59b7ed18c --- /dev/null +++ b/packages/core/vitest.config.ts @@ -0,0 +1,14 @@ +import path from "path"; + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + globals: true, + environment: "jsdom", + setupFiles: [path.resolve(__dirname, "./tests/setup.ts")], + hookTimeout: 60000, + testTimeout: 30000, + logHeapUsage: true + } +}); diff --git a/packages/deployer/package.json b/packages/deployer/package.json index fc5a5b754..8d22735c7 100644 --- a/packages/deployer/package.json +++ b/packages/deployer/package.json @@ -1,7 +1,7 @@ { "name": "@ark-project/deployer", "version": "1.0.1", - "description": "", + "description": "Ark project deployer", "main": "index.js", "private": true, "scripts": { @@ -14,17 +14,15 @@ "lint:fix": "eslint . --ext .ts --fix", "accounts:new": "npm run build && node ./dist/accounts/new.js", "accounts:deploy": "npm run build && node ./dist/accounts/deploy.js", - "deploy:starknet": "npm run build && node ./dist/deployStarknetContracts.js", - "deploy:starknet:tokens": "npm run build && node ./dist/deployStarknetFreemintNft.js", - "deploy:starknet:local": "tsx scripts/deploy-starknet-local.ts", - "deploy:solis": "npm run build && node ./dist/deployArkchainContracts.js", - "deploy:solis:local": "tsx scripts/deploy-solis-local.ts" + "deploy:starknet": "npm run build && node ./dist/deployArk.js", + "deploy:starknet:tokens": "npm run build && node ./dist/deployTokens.js", + "deploy:starknet:local": "tsx scripts/deploy.ts" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { - "commander": "^11.1.0", + "commander": "^12.1.0", "dotenv": "^16.3.1", "loading-cli": "^1.1.2", "node-fetch": "^3.3.2", @@ -32,10 +30,9 @@ "zod": "^3.22.4" }, "devDependencies": { - "@ark-project/core": "workspace:*", "@ark-project/eslint-config": "workspace:*", "@ark-project/typescript-config": "workspace:*", - "@types/node": "^20.10.7", + "@types/node": "^22.5.4", "tsx": "^4.11.0", "typescript": "^5.3.3" } diff --git a/packages/deployer/scripts/deploy-solis-local.ts b/packages/deployer/scripts/deploy-solis-local.ts deleted file mode 100644 index f1a0e2a71..000000000 --- a/packages/deployer/scripts/deploy-solis-local.ts +++ /dev/null @@ -1,97 +0,0 @@ -import fs from "fs"; -import { resolve } from "path"; - -import { Account } from "starknet"; - -import { ARTIFACTS_PATH } from "../src/constants"; -import { updateOrderbookAddress } from "../src/contracts/executor"; -import { - deployOrderBook, - updateExecutorAddress -} from "../src/contracts/orderbook"; -import { getSolisProvider, getStarknetProvider } from "../src/providers"; -import { setSolisAddresses } from "../src/solis"; - -const contractsFilePath = resolve(__dirname, "../../../contracts.dev.json"); - -async function getContracts() { - const contracts = await import(contractsFilePath); - - return contracts.default; -} - -async function run() { - if ( - !process.env.STARKNET_ADMIN_ADDRESS_DEV || - !process.env.STARKNET_ADMIN_PRIVATE_KEY_DEV || - !process.env.SOLIS_ADMIN_ADDRESS_DEV || - !process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV - ) { - console.error( - "Missing environment variables, see README.md for more information" - ); - process.exit(1); - } - - const contracts = await getContracts(); - const { provider: starknetProvider } = getStarknetProvider("dev"); - const { provider: solisProvider, nodeUrl: solisNodeUrl } = - getSolisProvider("dev"); - const starknetAdminAccount = new Account( - starknetProvider, - process.env.STARKNET_ADMIN_ADDRESS_DEV, - process.env.STARKNET_ADMIN_PRIVATE_KEY_DEV, - "1" - ); - const solisAdminAccount = new Account( - solisProvider, - process.env.SOLIS_ADMIN_ADDRESS_DEV, - process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV, - "1" - ); - const chainId = await starknetProvider.getChainId(); - - const orderbookContract = await deployOrderBook( - ARTIFACTS_PATH, - solisAdminAccount, - solisProvider, - solisAdminAccount.address, - chainId - ); - - await updateExecutorAddress( - solisProvider, - solisAdminAccount, - orderbookContract.address, - contracts.executor - ); - - await updateOrderbookAddress( - starknetProvider, - starknetAdminAccount, - contracts.executor, - orderbookContract.address - ); - - console.log("Orderbook contract deployed"); - await setSolisAddresses( - orderbookContract.address, - contracts.executor, - solisNodeUrl - ); - - const contractsContent = JSON.stringify( - { - ...contracts, - orderbook: orderbookContract.address - }, - null, - 2 - ); - - fs.writeFileSync(contractsFilePath, contractsContent); - - console.log(`Orderbook contract\t${orderbookContract.address}`); -} - -run(); diff --git a/packages/deployer/scripts/deploy-starknet-local.ts b/packages/deployer/scripts/deploy.ts similarity index 65% rename from packages/deployer/scripts/deploy-starknet-local.ts rename to packages/deployer/scripts/deploy.ts index 3da57f62d..da829eb37 100644 --- a/packages/deployer/scripts/deploy-starknet-local.ts +++ b/packages/deployer/scripts/deploy.ts @@ -8,15 +8,13 @@ import { deployERC20 } from "../src/contracts/erc20"; import { deployERC721 } from "../src/contracts/erc721"; import { deployERC721Royalties } from "../src/contracts/erc721royalties"; import { deployExecutor } from "../src/contracts/executor"; -import { deployMessaging } from "../src/contracts/messaging"; import { getFeeAddress } from "../src/providers"; +import { deployERC1155 } from "../src/contracts/erc1155"; async function run() { if ( !process.env.STARKNET_ADMIN_ADDRESS_DEV || - !process.env.STARKNET_ADMIN_PRIVATE_KEY_DEV || - !process.env.SOLIS_ADMIN_ADDRESS_DEV || - !process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + !process.env.STARKNET_ADMIN_PRIVATE_KEY_DEV ) { console.error( "Missing environment variables, see README.md for more information" @@ -31,26 +29,12 @@ async function run() { process.env.STARKNET_ADMIN_PRIVATE_KEY_DEV, "1" ); - const starknetSolisAccount = new Account( - provider, - process.env.SOLIS_ADMIN_ADDRESS_DEV, - process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV, - "1" - ); - - const messagingContract = await deployMessaging( - ARTIFACTS_PATH, - starknetAdminAccount, - provider, - starknetSolisAccount?.address || "" - ); const executorContract = await deployExecutor( ARTIFACTS_PATH, starknetAdminAccount, provider, - getFeeAddress("dev"), - messagingContract.address + getFeeAddress("dev") ); const ethContract = await deployERC20( @@ -84,29 +68,20 @@ async function run() { "0x29873c310fbefde666dc32a1554fea6bb45eecc84f680f8a2b0a8fbb8cb89af" ); - const messagingConfigFilePath = resolve( - __dirname, - "../../../crates/solis/messaging.local.json" + const erc1155Contract = await deployERC1155( + ARTIFACTS_PATH, + starknetAdminAccount, + provider ); - const messagingConfigContent = JSON.stringify({ - chain: "starknet", - rpc_url: "http://0.0.0.0:5050", - contract_address: messagingContract.address, - sender_address: process.env.STARKNET_SOLIS_ACCOUNT_ADDRESS_DEV, - private_key: process.env.STARKNET_SOLIS_ACCOUNT_PRIVATE_KEY_DEV, - interval: 2, - from_block: 0 - }); - await fs.writeFile(messagingConfigFilePath, messagingConfigContent); const contractsFilePath = resolve(__dirname, "../../../contracts.dev.json"); const contractsContent = JSON.stringify({ - messaging: messagingContract.address, executor: executorContract.address, nftContract: nftContract.address, nftContractFixedFees: nftContractFixedFees.address, nftContractRoyalties: nftContractRoyalties.address, - eth: ethContract.address + eth: ethContract.address, + erc1155: erc1155Contract.address, }); await fs.writeFile(contractsFilePath, contractsContent); } diff --git a/packages/deployer/src/contracts/erc1155.ts b/packages/deployer/src/contracts/erc1155.ts new file mode 100644 index 000000000..559f52f16 --- /dev/null +++ b/packages/deployer/src/contracts/erc1155.ts @@ -0,0 +1,29 @@ +import { Account, CallData, Contract, RpcProvider } from "starknet"; + +import { loadArtifacts } from "../contracts/common"; + +export async function deployERC1155( + artifactsPath: string, + deployerAccount: Account, + provider: RpcProvider +) { + const artifacts = loadArtifacts(artifactsPath, "ark_tokens_FreeMintERC1155"); + + const contractCallData = new CallData(artifacts.sierra.abi); + const contractConstructor = contractCallData.compile("constructor", { + base_uri: + "https://ipfs.io/ipfs/QmVXJ2eEx3xrD2mSdPqLBEEYM5obj6DRYkn5yant6rXPmw/" + }); + + const deployR = await deployerAccount.declareAndDeploy({ + contract: artifacts.sierra, + casm: artifacts.casm, + constructorCalldata: contractConstructor + }); + + return new Contract( + artifacts.sierra.abi, + deployR.deploy.contract_address, + provider + ); +} diff --git a/packages/deployer/src/contracts/erc721royalties.ts b/packages/deployer/src/contracts/erc721royalties.ts index 00a48c5ab..a124e51ef 100644 --- a/packages/deployer/src/contracts/erc721royalties.ts +++ b/packages/deployer/src/contracts/erc721royalties.ts @@ -48,7 +48,7 @@ export async function deployERC721Royalties( constructorCalldata: contractConstructor }); - setDefaultFees( + await setDefaultFees( provider, deployerAccount, deployR.deploy.contract_address, diff --git a/packages/deployer/src/contracts/executor.ts b/packages/deployer/src/contracts/executor.ts index 8638bd349..aa9a4c919 100644 --- a/packages/deployer/src/contracts/executor.ts +++ b/packages/deployer/src/contracts/executor.ts @@ -63,8 +63,7 @@ export async function deployExecutor( artifactsPath: string, account: sn.Account, provider: sn.RpcProvider, - ethContractAddress: string, - messagingAddress: string + ethContractAddress: string ) { const artifacts = getArtifacts(artifactsPath); const chain_id = await provider.getChainId(); @@ -72,7 +71,6 @@ export async function deployExecutor( const contractConstructor = contractCallData.compile("constructor", { admin_address: account.address, eth_contract_address: ethContractAddress, - messaging_address: messagingAddress, chain_id: chain_id }); diff --git a/packages/deployer/src/contracts/messaging.ts b/packages/deployer/src/contracts/messaging.ts deleted file mode 100644 index c2cb62a18..000000000 --- a/packages/deployer/src/contracts/messaging.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as sn from "starknet"; - -import * as common from "./common"; - -export async function upgradeMessaging( - artifactsPath: string, - deployerAccount: sn.Account, - provider: sn.RpcProvider, - contractAddress: string -) { - const artifacts = common.loadArtifacts( - artifactsPath, - "ark_starknet_appchain_messaging" - ); - - const { class_hash, transaction_hash } = await deployerAccount.declareIfNot({ - contract: artifacts.sierra, - casm: artifacts.casm - }); - - if (transaction_hash) { - await provider.waitForTransaction(transaction_hash); - } - - const { abi } = await provider.getClassAt(contractAddress); - if (abi === undefined) { - throw new Error("no abi."); - } - const messagingContract = new sn.Contract(abi, contractAddress, provider); - messagingContract.connect(deployerAccount); - const response = await messagingContract.upgrade(class_hash); - const transactionHash: string = response.transaction_hash; - if (transactionHash) { - await provider.waitForTransaction(transactionHash); - } - - return new sn.Contract(artifacts.sierra.abi, contractAddress, provider); -} - -/** - * Declare and deploys appchain_messaging contract. - * Returns the contract object. - */ -export async function deployMessaging( - artifactsPath: string, - deployerAccount: sn.Account, - provider: sn.RpcProvider, - appChainAccountAddress: string -) { - const artifacts = common.loadArtifacts( - artifactsPath, - "ark_starknet_appchain_messaging" - ); - - const contractCallData = new sn.CallData(artifacts.sierra.abi); - const contractConstructor = contractCallData.compile("constructor", { - owner: deployerAccount.address, - appchain_account: appChainAccountAddress - }); - - const deployR = await deployerAccount.declareAndDeploy({ - contract: artifacts.sierra, - casm: artifacts.casm, - constructorCalldata: contractConstructor - }); - - return new sn.Contract( - artifacts.sierra.abi, - deployR.deploy.contract_address, - provider - ); -} diff --git a/packages/deployer/src/contracts/orderbook.ts b/packages/deployer/src/contracts/orderbook.ts deleted file mode 100644 index da33c082d..000000000 --- a/packages/deployer/src/contracts/orderbook.ts +++ /dev/null @@ -1,90 +0,0 @@ -import * as sn from "starknet"; - -import { loadArtifacts } from "./common"; -import * as common from "./common"; - -/** - * Declare and deploys orderbook contract. - * Returns the contract object. - */ -export async function deployOrderBook( - artifactsPath: string, - account: sn.Account, - provider: sn.RpcProvider, - adminAddress: string, - chain_id: string -) { - const artifacts = loadArtifacts(artifactsPath, "ark_orderbook_orderbook"); - const contractCallData = new sn.CallData(artifacts.sierra.abi); - - const deployR = await account.declareAndDeploy({ - contract: artifacts.sierra, - casm: artifacts.casm, - constructorCalldata: contractCallData.compile("constructor", { - admin: adminAddress, - chain_id: chain_id - } as sn.RawArgs) - }); - - if (deployR.declare.transaction_hash) { - await provider.waitForTransaction(deployR.declare.transaction_hash); - } - - return new sn.Contract( - artifacts.sierra.abi, - deployR.deploy.contract_address, - provider - ); -} - -export async function upgradeOrderbook( - artifactsPath: string, - deployerAccount: sn.Account, - provider: sn.RpcProvider, - contractAddress: string -) { - const artifacts = common.loadArtifacts( - artifactsPath, - "ark_orderbook_orderbook" - ); - - const { class_hash, transaction_hash } = await deployerAccount.declareIfNot({ - contract: artifacts.sierra, - casm: artifacts.casm - }); - - if (transaction_hash) { - await provider.waitForTransaction(transaction_hash); - } - - const { abi } = await provider.getClassAt(contractAddress); - if (abi === undefined) { - throw new Error("no abi."); - } - const orderbookContract = new sn.Contract(abi, contractAddress, provider); - orderbookContract.connect(deployerAccount); - const response = await orderbookContract.upgrade(class_hash); - const transactionHash: string = response.transaction_hash; - if (transactionHash) { - await provider.waitForTransaction(transactionHash); - } - - return new sn.Contract(artifacts.sierra.abi, contractAddress, provider); -} - -export async function updateExecutorAddress( - provider: sn.RpcProvider, - deployerAccount: sn.Account, - contractAddress: string, - executorAddress: string -) { - const { abi } = await provider.getClassAt(contractAddress); - if (abi === undefined) { - throw new Error("no abi."); - } - const executorContract = new sn.Contract(abi, contractAddress, provider); - executorContract.connect(deployerAccount); - const response = - await executorContract.update_starknet_executor_address(executorAddress); - await provider.waitForTransaction(response.transaction_hash); -} diff --git a/packages/deployer/src/deployStarknetContracts.ts b/packages/deployer/src/deployArk.ts similarity index 53% rename from packages/deployer/src/deployStarknetContracts.ts rename to packages/deployer/src/deployArk.ts index deeacbfb1..2b2b3c821 100644 --- a/packages/deployer/src/deployStarknetContracts.ts +++ b/packages/deployer/src/deployArk.ts @@ -1,5 +1,4 @@ import { promises as fs } from "fs"; -import path from "path"; import { program } from "commander"; @@ -11,7 +10,6 @@ import loading from "loading-cli"; import { ARTIFACTS_PATH } from "./constants"; import { deployExecutor, upgradeExecutor } from "./contracts/executor"; -import { deployMessaging, upgradeMessaging } from "./contracts/messaging"; import { setArkFees, setDefaultCreatorFees } from "./contracts/setFees"; import { getFeeAddress, getStarknetProvider } from "./providers"; import { @@ -20,50 +18,19 @@ import { getStarknetAccounts } from "./utils"; -// Function to get the path for messaging.json -function getMessagingFilePath() { - return path.join(__dirname, "../../../messaging.json"); -} - async function deployStarknetContracts(starknetNetwork: ProviderNetwork) { console.log("\nSTARKNET NETWORK"); console.log("================\n"); console.log(`| Network | ${starknetNetwork}`); - const { provider: starknetProvider, nodeUrl: starknetNodeUrl } = - getStarknetProvider(starknetNetwork); - const { starknetAdminAccount, starknetSolisAccount } = - getStarknetAccounts(starknetNetwork); + const { provider: starknetProvider } = getStarknetProvider(starknetNetwork); + const { starknetAdminAccount } = getStarknetAccounts(starknetNetwork); const existingContracts = await getExistingContracts(); - console.log("\nSTARKNET ACCOUNTS"); console.log("=================\n"); console.log(`| Admin account | ${starknetAdminAccount.address}`); const starknetSpinner = loading("💅 Deploying Starknet Contracts...").start(); - let messagingContract; - if (existingContracts[starknetNetwork].messaging) { - console.log("⚡ Upgrading Messaging Contract..."); - starknetSpinner.text = "⚡ Upgrading Messaging Contract..."; - messagingContract = await upgradeMessaging( - ARTIFACTS_PATH, - starknetAdminAccount, - starknetProvider, - existingContracts[starknetNetwork].messaging - ); - } else { - console.log("⚡ Deploying Messaging Contract..."); - starknetSpinner.text = "⚡ Deploying Messaging Contract..."; - messagingContract = await deployMessaging( - ARTIFACTS_PATH, - starknetAdminAccount, - starknetProvider, - starknetSolisAccount?.address || "" - ); - existingContracts[starknetNetwork].messaging = messagingContract.address; - } - - starknetSpinner.text = "⚡ Deploying Executor Contract..."; let executorContract; if (existingContracts[starknetNetwork].executor) { console.log("⚡ Upgrading Executor Contract.."); @@ -80,50 +47,17 @@ async function deployStarknetContracts(starknetNetwork: ProviderNetwork) { ARTIFACTS_PATH, starknetAdminAccount, starknetProvider, - getFeeAddress(starknetNetwork), - messagingContract.address + getFeeAddress(starknetNetwork) ); existingContracts[starknetNetwork].executor = executorContract.address; } - // Determine from_block based on the network - let fromBlock; - if (starknetNetwork === "sepolia") { - fromBlock = 72242; - } else if (starknetNetwork === "mainnet") { - fromBlock = 644128; - } else { - fromBlock = 0; // default or handle other networks if any - } - - // Create the messaging file at the specified path - const messagingFilePath = getMessagingFilePath(); - const messagingFileContent = { - chain: "starknet", - rpc_url: starknetNodeUrl, - contract_address: messagingContract.address, - sender_address: starknetSolisAccount?.address, - private_key: starknetSolisAccount?.privateKey, - interval: 10, - from_block: fromBlock - }; - - console.log("\nMESSAGING FILE"); - console.log("==============\n"); - console.log(`| Contract | ${messagingFileContent}`); - - await fs.writeFile( - messagingFilePath, - JSON.stringify(messagingFileContent, null, 2) - ); - // Update the contracts.json file const contractsFilePath = getContractsFilePath(); const contractsContent = JSON.parse( await fs.readFile(contractsFilePath, "utf8") ); - contractsContent[starknetNetwork].messaging = messagingContract.address; contractsContent[starknetNetwork].executor = executorContract.address; await fs.writeFile( @@ -151,7 +85,6 @@ async function deployStarknetContracts(starknetNetwork: ProviderNetwork) { starknetSpinner.stop(); console.log("STARKNET CONTRACTS"); console.log("==================\n"); - console.log(`| Messaging contract | ${messagingContract.address}`); console.log(`| Executor contract | ${executorContract.address}`); } diff --git a/packages/deployer/src/deployArkchainContracts.ts b/packages/deployer/src/deployArkchainContracts.ts deleted file mode 100644 index 1e6529162..000000000 --- a/packages/deployer/src/deployArkchainContracts.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { promises as fs } from "fs"; - -import { program } from "commander"; -import loading from "loading-cli"; - -import { ARTIFACTS_PATH } from "./constants"; -import { updateOrderbookAddress } from "./contracts/executor"; -import { - deployOrderBook, - updateExecutorAddress, - upgradeOrderbook -} from "./contracts/orderbook"; -import { getSolisProvider, getStarknetProvider } from "./providers"; -import { setSolisAddresses } from "./solis"; -import { ProviderNetwork } from "./types"; -import { - getContractsFilePath, - getExistingContracts, - getSolisAccounts, - getStarknetAccounts -} from "./utils"; - -import "dotenv/config"; - -async function deployArkchainContracts( - starknetNetwork: ProviderNetwork, - solisNetwork: ProviderNetwork -) { - const { provider: starknetProvider } = getStarknetProvider(starknetNetwork); - const { provider: solisProvider, nodeUrl: solisNodeUrl } = - getSolisProvider(solisNetwork); - const { starknetAdminAccount } = getStarknetAccounts(starknetNetwork); - const { arkchainAdminAccount } = getSolisAccounts(solisNetwork); - - console.log("\nARKCHAIN ACCOUNTS"); - console.log("=================\n"); - if (arkchainAdminAccount) { - console.log(`| Admin account | ${arkchainAdminAccount.address}`); - } - - console.log("\n"); - - const arkchainSpinner = loading("💠 Deploying Arkchain Contracts...").start(); - - if (arkchainAdminAccount) { - const chain_id = await starknetProvider.getChainId(); - console.log("Chain ID: ", chain_id); - const existingContracts = await getExistingContracts(); - if (existingContracts[solisNetwork].orderbook) { - await upgradeOrderbook( - ARTIFACTS_PATH, - arkchainAdminAccount, - solisProvider, - existingContracts[solisNetwork].orderbook - ); - } else { - const orderbookContract = await deployOrderBook( - ARTIFACTS_PATH, - arkchainAdminAccount, - solisProvider, - arkchainAdminAccount.address, - chain_id - ); - existingContracts[solisNetwork].orderbook = orderbookContract.address; - arkchainSpinner.text = "💠 Updating executor address..."; - - await fs.writeFile( - getContractsFilePath(), - JSON.stringify(existingContracts) - ); - - await updateExecutorAddress( - solisProvider, - arkchainAdminAccount, - orderbookContract.address, - existingContracts[starknetNetwork].executor - ); - - arkchainSpinner.text = "💠 Updating Executor Contract on Starknet..."; - - if (starknetAdminAccount) { - await updateOrderbookAddress( - starknetProvider, - starknetAdminAccount, - existingContracts[starknetNetwork].executor, - orderbookContract.address - ); - } - - arkchainSpinner.text = "💠 Updating Contracts on solis rpc..."; - await setSolisAddresses( - orderbookContract.address, - existingContracts[starknetNetwork].executor, - solisNodeUrl - ); - - arkchainSpinner.stop(); - console.log("💠 Arkchain Contracts"); - console.log(`- Orderbook contract: ${orderbookContract.address}\n`); - } - } -} - -program.option("-sn, --starknet ", "Starknet Network", "dev"); -program.option("-so, --solis ", "Solis Network", "dev"); -program.parse(); - -const options = program.opts(); -const starknetNetwork = options.starknet; -const solisNetwork = options.solis; - -deployArkchainContracts(starknetNetwork, solisNetwork); diff --git a/packages/deployer/src/deployStarknetFreemintNft.ts b/packages/deployer/src/deployTokens.ts similarity index 89% rename from packages/deployer/src/deployStarknetFreemintNft.ts rename to packages/deployer/src/deployTokens.ts index 5196063c7..c820cd53f 100644 --- a/packages/deployer/src/deployStarknetFreemintNft.ts +++ b/packages/deployer/src/deployTokens.ts @@ -20,14 +20,18 @@ export async function deployStarknetContracts( const { starknetAdminAccount } = getStarknetAccounts(starknetNetwork); let existingContracts = await getExistingContracts(); - const artifacts = loadArtifacts(ARTIFACTS_PATH, "ark_tokens_FreeMintNFT"); + const artifacts = loadArtifacts( + ARTIFACTS_PATH, + "ark_tokens_FreeMintNFTRoyalty" + ); const contractCallData = new CallData(artifacts.sierra.abi); const contractConstructor = contractCallData.compile("constructor", { - name: "ARKSEPOLIA", - symbol: "ARKSEPOLIA", + name: "ARKSEPOLIA2981", + symbol: "ARKSEPOLIA2981", base_uri: - "https://ipfs.io/ipfs/QmVXJ2eEx3xrD2mSdPqLBEEYM5obj6DRYkn5yant6rXPmw/" + "https://ipfs.io/ipfs/QmVXJ2eEx3xrD2mSdPqLBEEYM5obj6DRYkn5yant6rXPmw/", + owner: starknetAdminAccount.address }); const deployR = await starknetAdminAccount.declareAndDeploy({ diff --git a/packages/deployer/src/providers.ts b/packages/deployer/src/providers.ts index 4015ad1a4..b5fb9828e 100644 --- a/packages/deployer/src/providers.ts +++ b/packages/deployer/src/providers.ts @@ -22,28 +22,6 @@ export function getStarknetProvider(starknetNetwork: string) { }; } -export function getSolisProvider(solisNetwork?: string) { - let solisNodeUrl: string; - switch (solisNetwork) { - case "dev": - solisNodeUrl = process.env.SOLIS_NODE_URL_DEV || ""; - break; - case "mainnet": - solisNodeUrl = process.env.SOLIS_NODE_URL_MAINNET || ""; - break; - case "sepolia": - solisNodeUrl = process.env.SOLIS_NODE_URL_SEPOLIA || ""; - break; - default: - throw new Error(`Unsupported solisNetwork: ${solisNetwork}`); - } - - return { - provider: new RpcProvider({ nodeUrl: solisNodeUrl }), - nodeUrl: solisNodeUrl - }; -} - export function getFeeAddress(network: string) { switch (network) { case "dev": diff --git a/packages/deployer/src/solis.ts b/packages/deployer/src/solis.ts deleted file mode 100644 index 6a3c212b3..000000000 --- a/packages/deployer/src/solis.ts +++ /dev/null @@ -1,44 +0,0 @@ -export async function setSolisAddresses( - orderbookAddress: string, - executorAddress: string, - nodeUrl: string -) { - const url = nodeUrl; - const user = process.env.RPC_USER; - const password = process.env.RPC_PASSWORD; - if (!user || !password) { - throw new Error("RPC_USER and RPC_PASSWORD must be set in the .env file"); - } - const basic_auth = Buffer.from(`${user}:${password}`).toString("base64"); - const postData = { - jsonrpc: "2.0", - id: "1", - method: "solis_setSolisAddresses", - params: { - addresses: { - orderbook_arkchain: orderbookAddress, - executor_starknet: executorAddress - }, - basic_auth - } - }; - - try { - const response = await fetch(url, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify(postData) - }); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - await response.json(); - console.log("Ok"); - } catch (error) { - console.error("Error:", error); - } -} diff --git a/packages/deployer/src/utils/accounts.ts b/packages/deployer/src/utils/accounts.ts index a082e9412..30f3fc1f7 100644 --- a/packages/deployer/src/utils/accounts.ts +++ b/packages/deployer/src/utils/accounts.ts @@ -9,11 +9,11 @@ export const getNetworkVarName = ( ): string => `${type}_${accountType}_ADDRESS_${network.toUpperCase()}`; export const filterAccounts = ( - accounts: { address: string; privateKey: string; publicKey: string }[], + accounts: { address: string; privateKey: string; }[], network: ProviderNetwork, type: string, accountType: string -): { address: string; privateKey: string; publicKey: string } | undefined => { +): { address: string; privateKey: string; } | undefined => { return accounts.find((account) => { const envVarName = getNetworkVarName(network, type, accountType); const envAddress = process.env[envVarName]; @@ -25,10 +25,9 @@ export const buildAccounts = ( provider: RpcProvider, accountData: | { - address: string; - privateKey: string; - publicKey: string; - } + address: string; + privateKey: string; + } | undefined ): Account => { if (!accountData) { diff --git a/packages/deployer/src/utils/contract.ts b/packages/deployer/src/utils/contract.ts index 5fd1d5638..29c2b9cd8 100644 --- a/packages/deployer/src/utils/contract.ts +++ b/packages/deployer/src/utils/contract.ts @@ -7,7 +7,9 @@ export function getContractsFilePath() { export async function getExistingContracts() { try { + console.log(getContractsFilePath()); const fileContent = await fs.readFile(getContractsFilePath(), "utf8"); + console.log("fileContent", fileContent); const jsonContent = JSON.parse(fileContent); return jsonContent; } catch (error) { diff --git a/packages/deployer/src/utils/index.ts b/packages/deployer/src/utils/index.ts index 7a21083a4..e67a19787 100644 --- a/packages/deployer/src/utils/index.ts +++ b/packages/deployer/src/utils/index.ts @@ -1,4 +1,2 @@ -export { getMessagingFilePath } from "./path"; export { getContractsFilePath, getExistingContracts } from "./contract"; export { getStarknetAccounts } from "./starknetAccounts"; -export { getSolisAccounts } from "./solisAccounts"; diff --git a/packages/deployer/src/utils/solisAccounts.ts b/packages/deployer/src/utils/solisAccounts.ts deleted file mode 100644 index cb040a2c1..000000000 --- a/packages/deployer/src/utils/solisAccounts.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { getSolisProvider } from "../providers"; -import { ProviderNetwork } from "../types"; -import { buildAccounts, filterAccounts } from "./accounts"; - -import "dotenv/config"; - -export function getSolisAccounts(solisNetwork: ProviderNetwork) { - const { provider: solisProvider } = getSolisProvider(solisNetwork); - - const solisAdminAccounts = [ - { - address: process.env.SOLIS_ADMIN_ADDRESS_DEV || "", - privateKey: process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV || "", - publicKey: process.env.SOLIS_ADMIN_PUBLIC_KEY_DEV || "" - }, - { - address: process.env.SOLIS_ADMIN_ADDRESS_SEPOLIA || "", - privateKey: process.env.SOLIS_ADMIN_PRIVATE_KEY_SEPOLIA || "", - publicKey: process.env.SOLIS_ADMIN_PUBLIC_KEY_SEPOLIA || "" - }, - { - address: process.env.SOLIS_ADMIN_ADDRESS_MAINNET || "", - privateKey: process.env.SOLIS_ADMIN_PRIVATE_KEY_MAINNET || "", - publicKey: process.env.SOLIS_ADMIN_PUBLIC_KEY_MAINNET || "" - } - ]; - - const filteredSolisAccounts = filterAccounts( - solisAdminAccounts, - solisNetwork, - "SOLIS", - "ADMIN" - ); - - return { - arkchainAdminAccount: buildAccounts(solisProvider, filteredSolisAccounts) - }; -} diff --git a/packages/deployer/src/utils/starknetAccounts.ts b/packages/deployer/src/utils/starknetAccounts.ts index 54269a4d0..cff04b1a8 100644 --- a/packages/deployer/src/utils/starknetAccounts.ts +++ b/packages/deployer/src/utils/starknetAccounts.ts @@ -11,35 +11,14 @@ export function getStarknetAccounts(starknetNetwork: ProviderNetwork) { { address: process.env.STARKNET_ADMIN_ADDRESS_DEV || "", privateKey: process.env.STARKNET_ADMIN_PRIVATE_KEY_DEV || "", - publicKey: process.env.STARKNET_ADMIN_PUBLIC_KEY_DEV || "" }, { address: process.env.STARKNET_ADMIN_ADDRESS_SEPOLIA || "", privateKey: process.env.STARKNET_ADMIN_PRIVATE_KEY_SEPOLIA || "", - publicKey: process.env.STARKNET_ADMIN_PUBLIC_KEY_SEPOLIA || "" }, { address: process.env.STARKNET_ADMIN_ADDRESS_MAINNET || "", privateKey: process.env.STARKNET_ADMIN_PRIVATE_KEY_MAINNET || "", - publicKey: process.env.STARKNET_ADMIN_PUBLIC_KEY_MAINNET || "" - } - ]; - - const starknetAppchainAccounts = [ - { - address: process.env.STARKNET_SOLIS_ACCOUNT_ADDRESS_DEV || "", - privateKey: process.env.STARKNET_SOLIS_ACCOUNT_PRIVATE_KEY_DEV || "", - publicKey: process.env.STARKNET_SOLIS_ACCOUNT_PUBLIC_KEY_DEV || "" - }, - { - address: process.env.STARKNET_SOLIS_ACCOUNT_ADDRESS_SEPOLIA || "", - privateKey: process.env.STARKNET_SOLIS_ACCOUNT_PRIVATE_KEY_SEPOLIA || "", - publicKey: process.env.STARKNET_SOLIS_ACCOUNT_PUBLIC_KEY_SEPOLIA || "" - }, - { - address: process.env.STARKNET_SOLIS_ACCOUNT_ADDRESS_MAINNET || "", - privateKey: process.env.STARKNET_SOLIS_ACCOUNT_PRIVATE_KEY_MAINNET || "", - publicKey: process.env.STARKNET_SOLIS_ACCOUNT_PUBLIC_KEY_MAINNET || "" } ]; @@ -50,15 +29,7 @@ export function getStarknetAccounts(starknetNetwork: ProviderNetwork) { "ADMIN" ); - const filteredStarknetExecutorAccounts = filterAccounts( - starknetAppchainAccounts, - starknetNetwork, - "STARKNET", - "SOLIS_ACCOUNT" - ); - return { - starknetSolisAccount: filteredStarknetExecutorAccounts, starknetAdminAccount: buildAccounts( starknetProvider, filteredStarknetAccounts diff --git a/packages/deployer/tsconfig.build.json b/packages/deployer/tsconfig.build.json index 21ce5dc83..64813f726 100644 --- a/packages/deployer/tsconfig.build.json +++ b/packages/deployer/tsconfig.build.json @@ -6,6 +6,11 @@ "declarationDir": "./dist", "sourceMap": true }, - "include": ["**/*.ts"], - "exclude": ["node_modules", "scripts"] -} + "include": [ + "**/*.ts" + ], + "exclude": [ + "node_modules", + "scripts" + ] +} \ No newline at end of file diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index de8756672..7480ed822 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -14,7 +14,7 @@ "@typescript-eslint/parser": "^6.11.0", "@vercel/style-guide": "^5.1.0", "eslint-config-prettier": "^9.0.0", - "eslint-config-turbo": "^1.10.12", + "eslint-config-turbo": "^2.1.2", "eslint-plugin-only-warn": "^1.1.0", "typescript": "^5.2.2" }, diff --git a/packages/eslint-config/react-internal.js b/packages/eslint-config/react-internal.js index 7ef335f78..b96fc9653 100644 --- a/packages/eslint-config/react-internal.js +++ b/packages/eslint-config/react-internal.js @@ -14,7 +14,7 @@ const project = resolve(process.cwd(), "tsconfig.json"); /** @type {import("eslint").Linter.Config} */ module.exports = { - extends: ["eslint:recommended", "prettier", "eslint-config-turbo"], + extends: ["eslint:recommended", "prettier", "turbo"], plugins: ["only-warn"], env: { browser: true diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index d105d3d24..188af1341 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,42 @@ # @ark-project/react +## 2.0.0-beta.4 + +### Patch Changes + +- Export query provider + +## 2.0.0-beta.3 + +### Patch Changes + +- Export query provider + +## 2.0.0-beta.2 + +### Minor Changes + +- Update for provider + +## 2.0.0-beta.1 + +### Patch Changes + +- 6d31848: Update contract address +- Updated dependencies [6d31848] + - @ark-project/core@3.0.0-beta.0 + +## 2.0.0-beta.0 + +### Major Changes + +- Update SDKs + +### Patch Changes + +- Updated dependencies + - @ark-project/core@3.0.0-beta.0 + ## 1.1.2 ### Patch Changes diff --git a/packages/react/hooks/index.ts b/packages/react/hooks/index.ts deleted file mode 100644 index 5d2247624..000000000 --- a/packages/react/hooks/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export { default as useCancel } from "./useCancel"; -export { default as useCreateListing } from "./useCreateListing"; -export { default as useCreateAuction } from "./useCreateAuction"; -export { default as useCreateOffer } from "./useCreateOffer"; -export { default as useFulfillListing } from "./useFulfillListing"; -export { default as useFulfillAuction } from "./useFulfillAuction"; -export { default as useFulfillOffer } from "./useFulfillOffer"; -export { useConfig } from "./useConfig"; diff --git a/packages/react/package.json b/packages/react/package.json index 95296f340..7a59f70b5 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,37 +1,51 @@ { - "name": "@ark-project/react", - "version": "1.1.2", - "description": "", - "main": "./dist/esm/src/index.js", - "types": "./dist/types/src/index.d.ts", - "typings": "./dist/types/src/index.d.ts", - "scripts": { - "build": "pnpm build:clean && pnpm build:esm+types", - "build:clean": "rm -rf dist", - "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", - "clean": "rm -rf .turbo dist node_modules tsconfig.tsbuildinfo", - "lint": "eslint --ext .ts,.tsx .", - "lint:fix": "eslint --ext .ts,.tsx . --fix", - "test": "echo \"Error: no test specified\" && exit 1", - "dev": "nodemon --watch src --exec \"pnpm run build\"" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@ark-project/core": "workspace:*", - "@starknet-react/chains": "^0.1.7", - "@starknet-react/core": "^2.8.1", - "get-starknet-core": "^3.3.0", - "react": "^18", - "react-dom": "^18", - "starknet": "^6.9.0" - }, - "devDependencies": { - "@ark-project/eslint-config": "workspace:*", - "@ark-project/typescript-config": "workspace:*", - "@types/react": "^18", - "nodemon": "^3.0.2", - "typescript": "^5.3.3" - } + "name": "@ark-project/react", + "version": "2.0.0-beta.4", + "description": "", + "main": "./dist/esm/src/index.js", + "types": "./dist/types/src/index.d.ts", + "typings": "./dist/types/src/index.d.ts", + "scripts": { + "build": "pnpm build:clean && pnpm build:esm+types", + "build:clean": "rm -rf dist", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "clean": "rm -rf .turbo dist node_modules tsconfig.tsbuildinfo", + "lint": "eslint --ext .ts,.tsx .", + "lint:fix": "eslint --ext .ts,.tsx . --fix", + "test": "vitest --no-file-parallelism", + "typecheck": "tsc --noEmit", + "dev": "nodemon --watch src --exec \"pnpm run build\"" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@ark-project/core": "workspace:*", + "@starknet-react/chains": "^3.1.2", + "@starknet-react/core": "^3.7.2", + "@tanstack/react-query": "^5.68.0", + "get-starknet-core": "^3.3.5", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "starknet": "^6.23.1" + }, + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "@ark-project/eslint-config": "workspace:*", + "@ark-project/test": "workspace:*", + "@ark-project/typescript-config": "workspace:*", + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.2.0", + "@testing-library/react-hooks": "^8.0.1", + "@types/react": "^18.3.18", + "dotenv": "^16.4.7", + "jest-environment-jsdom": "^29.7.0", + "nodemon": "^3.1.9", + "react-test-renderer": "^18.3.1", + "typescript": "^5.8.2", + "vitest": "^2.1.9" + } } diff --git a/packages/react/src/components/ArkProvider.tsx b/packages/react/src/components/ArkProvider.tsx index a788a898d..40cde2af3 100644 --- a/packages/react/src/components/ArkProvider.tsx +++ b/packages/react/src/components/ArkProvider.tsx @@ -1,26 +1,16 @@ "use client"; -import React, { - createContext, - PropsWithChildren, - useEffect, - useState -} from "react"; +import React, { createContext, PropsWithChildren, useMemo } from "react"; -import { useAccount, useNetwork, useProvider } from "@starknet-react/core"; +import { useNetwork, useProvider } from "@starknet-react/core"; import { Config, createConfig, - CreateConfigParameters, - Network + CreateConfigParameters } from "@ark-project/core"; -import { getOwner } from "../lib/getOwner"; -import { RpcProviderProvider } from "./RpcContext"; - -const OwnerDataContext = createContext(undefined); -const ConfigDataContext = createContext(undefined); +const ArkContext = createContext(undefined); export type ArkProviderProviderProps = { config: CreateConfigParameters; @@ -28,53 +18,20 @@ export type ArkProviderProviderProps = { function ArkProvider(props: PropsWithChildren) { const { children, config: baseConfig } = props; - const [owner, setOwner] = useState(undefined); - const { provider: starknetProvider } = useProvider(); - const { chain: starknetChain } = useNetwork(); - const [config, setConfig] = useState( - createConfig({ - starknetProvider: starknetProvider, - starknetNetwork: baseConfig.starknetNetwork as Network, - arkchainNetwork: baseConfig.arkchainNetwork as Network - }) + const { provider } = useProvider(); + const { chain } = useNetwork(); + + const config = useMemo( + () => + createConfig({ + ...baseConfig, + starknetProvider: provider, + starknetNetwork: baseConfig.starknetNetwork + }), + [chain, provider, baseConfig.starknetNetwork] ); - useEffect(() => { - const newConfig = createConfig({ - starknetProvider: starknetProvider, - starknetNetwork: baseConfig.starknetNetwork as Network, - arkchainNetwork: baseConfig.arkchainNetwork as Network - }); - setConfig(newConfig); - }, [starknetProvider, starknetChain, baseConfig]); - - const { address, connector } = useAccount(); - - useEffect(() => { - const fetchOwner = async () => { - if (address && config.starknetProvider && connector?.id) { - const owner = await getOwner( - address, - config.starknetProvider, - connector?.id - ); - if (Array.isArray(owner) && owner[0]) { - setOwner(owner[0]); - } - } else { - setOwner(undefined); - } - }; - fetchOwner(); - }, [address, config.starknetProvider, connector]); - - return ( - - - {children} - - - ); + return {children}; } -export { ArkProvider, OwnerDataContext, ConfigDataContext }; +export { ArkContext, ArkProvider }; diff --git a/packages/react/src/components/RpcContext.tsx b/packages/react/src/components/RpcContext.tsx deleted file mode 100644 index e5eea7a02..000000000 --- a/packages/react/src/components/RpcContext.tsx +++ /dev/null @@ -1,36 +0,0 @@ -"use client"; - -import React, { createContext, useMemo, type PropsWithChildren } from "react"; - -import { RpcProvider } from "starknet"; - -import { Config } from "@ark-project/core"; - -type RpcContextValue = - | { - rpcProvider: RpcProvider; - } - | undefined; - -export type RpcProviderProviderProps = { - config: Config; -}; - -export const RpcContext = createContext(undefined); - -export function RpcProviderProvider( - props: PropsWithChildren -) { - const { children, config } = props; - - const arkChain = useMemo( - () => ({ - rpcProvider: new RpcProvider({ - nodeUrl: config.arkchainRpcUrl - }) - }), - [config.arkchainRpcUrl] - ); - - return {children}; -} diff --git a/packages/react/src/hooks/useArkFees.test.ts b/packages/react/src/hooks/useArkFees.test.ts new file mode 100644 index 000000000..fe5d492c2 --- /dev/null +++ b/packages/react/src/hooks/useArkFees.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from "vitest"; + +import { renderHook, waitFor } from "../../test/react"; +import { useArkFees } from "./useArkFees"; + +describe("useArkFees", () => { + it("default", async () => { + const { result } = renderHook(() => useArkFees()); + + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + + expect(result.current.data).toMatchInlineSnapshot(` + { + "denominator": 1n, + "formatted": "0.00", + "numerator": 0n, + } + `); + }); +}); diff --git a/packages/react/src/hooks/useArkFees.ts b/packages/react/src/hooks/useArkFees.ts new file mode 100644 index 000000000..7fd7f7bc7 --- /dev/null +++ b/packages/react/src/hooks/useArkFees.ts @@ -0,0 +1,24 @@ +"use client"; + +import { useQuery } from "@tanstack/react-query"; + +import { getArkFees } from "@ark-project/core"; + +import { useConfig } from "./useConfig"; + +function useArkFees() { + const config = useConfig(); + + return useQuery({ + queryKey: ["getArkFees"], + queryFn: async () => { + if (!config) { + throw new Error("Config not found"); + } + + return getArkFees(config); + } + }); +} + +export { useArkFees }; diff --git a/packages/react/src/hooks/useBrokerFees.test.ts b/packages/react/src/hooks/useBrokerFees.test.ts new file mode 100644 index 000000000..8218b0429 --- /dev/null +++ b/packages/react/src/hooks/useBrokerFees.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from "vitest"; + +import { accounts } from "@ark-project/test"; + +import { renderHook, waitFor } from "../../test/react"; +import { useBrokerFees } from "./useBrokerFees"; + +describe("useBrokerFees", () => { + it("default", async () => { + const { listingBroker } = accounts; + + const { result } = renderHook(() => + useBrokerFees({ brokerAdress: listingBroker.address }) + ); + + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + + expect(result.current.data).toMatchInlineSnapshot(` + { + "denominator": 1n, + "formatted": "0.00", + "numerator": 0n, + } + `); + }); +}); diff --git a/packages/react/src/hooks/useBrokerFees.ts b/packages/react/src/hooks/useBrokerFees.ts new file mode 100644 index 000000000..59fdf1af1 --- /dev/null +++ b/packages/react/src/hooks/useBrokerFees.ts @@ -0,0 +1,28 @@ +"use client"; + +import { useQuery } from "@tanstack/react-query"; + +import { getBrokerFees } from "@ark-project/core"; + +import { useConfig } from "./useConfig"; + +interface UseBrokerFeesParams { + brokerAdress: string; +} + +function useBrokerFees({ brokerAdress }: UseBrokerFeesParams) { + const config = useConfig(); + + return useQuery({ + queryKey: ["getBrokerFees", brokerAdress], + queryFn: async () => { + if (!config) { + throw new Error("Config not found"); + } + + return getBrokerFees(config, brokerAdress); + } + }); +} + +export { useBrokerFees }; diff --git a/packages/react/src/hooks/useCancel.test.ts b/packages/react/src/hooks/useCancel.test.ts new file mode 100644 index 000000000..9bf36e358 --- /dev/null +++ b/packages/react/src/hooks/useCancel.test.ts @@ -0,0 +1,63 @@ +import { useAccount, useConnect, useDisconnect } from "@starknet-react/core"; +import { describe, expect, it } from "vitest"; + +import { + accounts, + defaultConnector, + mintERC20, + mintERC721 +} from "@ark-project/test"; + +import { act, renderHook, waitFor } from "../../test/react"; +import useCreateOffer from "./useCreateOffer"; + +function useCreateOfferWithConnect() { + return { + createOffer: useCreateOffer(), + account: useAccount(), + connect: useConnect(), + disconnect: useDisconnect() + }; +} + +describe("useCancelOffer", () => { + it("default", async () => { + const { seller } = accounts; + const { result } = renderHook(() => useCreateOfferWithConnect()); + + await act(async () => { + await result.current.connect.connectAsync({ + connector: defaultConnector + }); + }); + + const buyer = result.current.account.account; + + expect(seller).toBeDefined(); + + if (!buyer) { + return; + } + + await act(async () => { + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + await mintERC20({ account: buyer, amount: 1000 }); + + await result.current.createOffer.createOfferAsync({ + account: buyer, + brokerAddress: accounts.listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1000) + }); + }); + + await waitFor(() => + expect(result.current.createOffer.isSuccess).toBe(true) + ); + + await act(async () => { + await result.current.disconnect.disconnectAsync(); + }); + }, 50_000); +}); diff --git a/packages/react/src/hooks/useCancel.ts b/packages/react/src/hooks/useCancel.ts index ded8dbcaf..04035994f 100644 --- a/packages/react/src/hooks/useCancel.ts +++ b/packages/react/src/hooks/useCancel.ts @@ -1,44 +1,30 @@ "use client"; -import { useState } from "react"; +import { useMutation } from "@tanstack/react-query"; -import { AccountInterface } from "starknet"; +import { cancelOrder, CancelOrderParameters } from "@ark-project/core"; -import { - CancelInfo, - cancelOrder as cancelOrderCore, - Config -} from "@ark-project/core"; - -import { Status } from "../types"; import { useConfig } from "./useConfig"; -type CancelParameters = { - starknetAccount: AccountInterface; -} & CancelInfo; - function useCancel() { - const [status, setStatus] = useState("idle"); const config = useConfig(); - async function cancel(parameters: CancelParameters) { - try { - setStatus("loading"); - await cancelOrderCore(config as Config, { - starknetAccount: parameters.starknetAccount, - cancelInfo: { - orderHash: parameters.orderHash, - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId - } - }); - setStatus("success"); - } catch (error) { - setStatus("error"); - console.error(error); + + const { mutate, mutateAsync, ...result } = useMutation({ + mutationKey: ["cancel"], + mutationFn: async (parameters: CancelOrderParameters) => { + if (!config) { + throw new Error("config not loaded"); + } + + return cancelOrder(config, parameters); } - } + }); - return { cancel, status }; + return { + ...result, + cancel: mutate, + cancelAsync: mutateAsync + }; } export { useCancel }; diff --git a/packages/react/src/hooks/useCancelCollectionOffer.ts b/packages/react/src/hooks/useCancelCollectionOffer.ts new file mode 100644 index 000000000..8b6119349 --- /dev/null +++ b/packages/react/src/hooks/useCancelCollectionOffer.ts @@ -0,0 +1,43 @@ +"use client"; + +import { useState } from "react"; + +import { AccountInterface } from "starknet"; + +import { + cancelCollectionOffer, + CancelCollectionOfferInfo, + Config +} from "@ark-project/core"; + +import { Status } from "../types"; +import { useConfig } from "./useConfig"; + +type CancelParameters = { + starknetAccount: AccountInterface; +} & CancelCollectionOfferInfo; + +function useCancelCollectionOffer() { + const [status, setStatus] = useState("idle"); + const config = useConfig(); + async function cancel(parameters: CancelParameters) { + try { + setStatus("loading"); + await cancelCollectionOffer(config as Config, { + starknetAccount: parameters.starknetAccount, + cancelInfo: { + orderHash: parameters.orderHash, + tokenAddress: parameters.tokenAddress + } + }); + setStatus("success"); + } catch (error) { + setStatus("error"); + console.error(error); + } + } + + return { cancel, status }; +} + +export { useCancelCollectionOffer }; diff --git a/packages/react/src/hooks/useCollectionCreatorFees.test.ts b/packages/react/src/hooks/useCollectionCreatorFees.test.ts new file mode 100644 index 000000000..9a3ca9b6d --- /dev/null +++ b/packages/react/src/hooks/useCollectionCreatorFees.test.ts @@ -0,0 +1,30 @@ +import { describe, expect, it } from "vitest"; + +import { accounts, mintERC721 } from "@ark-project/test"; + +import { renderHook, waitFor } from "../../test/react"; +import { useCollectionCreatorFees } from "./useCollectionCreatorFees"; + +describe("useCollectionCreatorFees", () => { + it("default", async () => { + const { seller } = accounts; + const { tokenAddress } = await mintERC721({ account: seller }); + + const { result } = renderHook(() => + useCollectionCreatorFees({ tokenAddress }) + ); + + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + + expect(result.current.data).toMatchInlineSnapshot(` + { + "creator": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", + "fees": { + "denominator": 1n, + "formatted": "0.00", + "numerator": 0n, + }, + } + `); + }); +}); diff --git a/packages/react/src/hooks/useCollectionCreatorFees.ts b/packages/react/src/hooks/useCollectionCreatorFees.ts new file mode 100644 index 000000000..be60b53c2 --- /dev/null +++ b/packages/react/src/hooks/useCollectionCreatorFees.ts @@ -0,0 +1,32 @@ +"use client"; + +import { useQuery } from "@tanstack/react-query"; + +import { getCollectionCreatorFees } from "@ark-project/core"; + +import { useConfig } from "./useConfig"; + +interface UseCollectionCreatorFeesParams { + tokenAddress: string; +} + +function useCollectionCreatorFees({ + tokenAddress +}: UseCollectionCreatorFeesParams) { + const config = useConfig(); + + return useQuery({ + queryKey: ["getCollectionCreatorFees", tokenAddress], + queryFn: async () => { + if (!config) { + throw new Error("Config not found"); + } + + const fees = await getCollectionCreatorFees(config, tokenAddress); + + return fees; + } + }); +} + +export { useCollectionCreatorFees }; diff --git a/packages/react/src/hooks/useConfig.ts b/packages/react/src/hooks/useConfig.ts index 5d2cd0ff3..4b3f79a2f 100644 --- a/packages/react/src/hooks/useConfig.ts +++ b/packages/react/src/hooks/useConfig.ts @@ -2,10 +2,15 @@ import { useContext } from "react"; -import { ConfigDataContext } from "../components/ArkProvider"; +import { ArkContext } from "../components/ArkProvider"; function useConfig() { - const context = useContext(ConfigDataContext); + const context = useContext(ArkContext); + + if (context === undefined) { + throw new Error("useConfig must be used within a ArkProvider"); + } + return context; } diff --git a/packages/react/src/hooks/useCreateAuction.test.ts b/packages/react/src/hooks/useCreateAuction.test.ts new file mode 100644 index 000000000..90b0c788d --- /dev/null +++ b/packages/react/src/hooks/useCreateAuction.test.ts @@ -0,0 +1,48 @@ +import { useAccount, useConnect, useDisconnect } from "@starknet-react/core"; +import { describe, expect, it } from "vitest"; + +import { accounts, defaultConnector, mintERC721 } from "@ark-project/test"; + +import { act, renderHook, waitFor } from "../../test/react"; +import { useCreateAuction } from "./useCreateAuction"; + +function useCreateAuctionWithConnect() { + return { + mutation: useCreateAuction(), + account: useAccount(), + connect: useConnect(), + disconnect: useDisconnect() + }; +} + +describe("useCreateAuction", () => { + it("default", async () => { + const { result } = renderHook(() => useCreateAuctionWithConnect()); + + await act(async () => { + await result.current.connect.connectAsync({ + connector: defaultConnector + }); + }); + + await act(async () => { + const seller = await defaultConnector.account(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + + await result.current.mutation.createAuctionAsync({ + account: seller, + brokerAddress: accounts.listingBroker.address, + tokenAddress, + tokenId, + startAmount: BigInt(1000), + endAmount: BigInt(2000) + }); + }); + + await waitFor(() => expect(result.current.mutation.isSuccess).toBe(true)); + + await act(async () => { + await result.current.disconnect.disconnectAsync(); + }); + }, 20_000); +}); diff --git a/packages/react/src/hooks/useCreateAuction.ts b/packages/react/src/hooks/useCreateAuction.ts index 271501cc1..c29b6f487 100644 --- a/packages/react/src/hooks/useCreateAuction.ts +++ b/packages/react/src/hooks/useCreateAuction.ts @@ -1,61 +1,32 @@ "use client"; -import { useState } from "react"; +import { useMutation } from "@tanstack/react-query"; -import { AccountInterface } from "starknet"; +import { createAuction, CreateAuctionParameters } from "@ark-project/core"; -import { AuctionV1, Config, createAuction } from "@ark-project/core"; - -import { Status } from "../types"; import { useConfig } from "./useConfig"; -export type CreateAuctionParameters = { - starknetAccount: AccountInterface; -} & AuctionV1; - export default function useCreateAuction() { - const [status, setStatus] = useState("idle"); - const [response, setResponse] = useState(); const config = useConfig(); - async function create(parameters: CreateAuctionParameters) { - if (!config) { - throw new Error("config not loaded"); - } + const { mutate, mutateAsync, ...result } = useMutation({ + mutationKey: ["createAuction"], + mutationFn: async (parameters: CreateAuctionParameters) => { + if (!config) { + throw new Error("config not loaded"); + } + + const result = await createAuction(config, parameters); - setStatus("loading"); - - try { - const orderHash = await createAuction(config as Config, { - starknetAccount: parameters.starknetAccount, - order: { - startAmount: parameters.startAmount, - endAmount: parameters.endAmount, - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId, - currencyAddress: - parameters.currencyAddress || config.starknetCurrencyContract, - currencyChainId: - parameters.currencyChainId || config.starknetProvider.getChainId(), - brokerId: parameters.brokerId, - startDate: parameters.startDate, - endDate: parameters.endDate - } as AuctionV1, - approveInfo: { - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId - } - }); - - setResponse(orderHash); - setStatus("success"); - } catch (error) { - console.error("error: failed to create auction", error); - setStatus("error"); + return result; } - } + }); - return { create, status, response }; + return { + ...result, + createAuction: mutate, + createAuctionAsync: mutateAsync + }; } export { useCreateAuction }; diff --git a/packages/react/src/hooks/useCreateCollectionOffer.test.ts b/packages/react/src/hooks/useCreateCollectionOffer.test.ts new file mode 100644 index 000000000..708066ea6 --- /dev/null +++ b/packages/react/src/hooks/useCreateCollectionOffer.test.ts @@ -0,0 +1,58 @@ +import { useAccount, useConnect, useDisconnect } from "@starknet-react/core"; +import { describe, expect, it } from "vitest"; + +import { + accounts, + defaultConnector, + mintERC20, + mintERC721 +} from "@ark-project/test"; + +import { act, renderHook, waitFor } from "../../test/react"; +import useCreateCollectionOffer from "./useCreateCollectionOffer"; + +function useCreateCollectionOfferWithConnect() { + return { + mutation: useCreateCollectionOffer(), + account: useAccount(), + connect: useConnect(), + disconnect: useDisconnect() + }; +} + +describe("useCreateCollectionOffer", () => { + it("default", async () => { + const { seller } = accounts; + const { result } = renderHook(() => useCreateCollectionOfferWithConnect()); + + await act(async () => { + await result.current.connect.connectAsync({ + connector: defaultConnector + }); + }); + + await act(async () => { + const buyer = result.current.account.account; + + if (!buyer) { + throw new Error("Account not connected"); + } + + const { tokenAddress } = await mintERC721({ account: seller }); + await mintERC20({ account: buyer, amount: 1000 }); + + await result.current.mutation.createCollectionOfferAsync({ + account: buyer, + brokerAddress: accounts.listingBroker.address, + tokenAddress, + amount: BigInt(1000) + }); + }); + + await waitFor(() => expect(result.current.mutation.isSuccess).toBe(true)); + + await act(async () => { + await result.current.disconnect.disconnectAsync(); + }); + }, 10_000); +}); diff --git a/packages/react/src/hooks/useCreateCollectionOffer.ts b/packages/react/src/hooks/useCreateCollectionOffer.ts new file mode 100644 index 000000000..e9c953d33 --- /dev/null +++ b/packages/react/src/hooks/useCreateCollectionOffer.ts @@ -0,0 +1,33 @@ +"use client"; + +import { useMutation } from "@tanstack/react-query"; + +import { + createCollectionOffer, + CreateCollectionOfferParameters +} from "@ark-project/core"; + +import { useConfig } from "./useConfig"; + +export default function useCreateCollectionOffer() { + const config = useConfig(); + + const { mutate, mutateAsync, ...result } = useMutation({ + mutationKey: ["useCreatecollectionOffer"], + mutationFn: async (parameters: CreateCollectionOfferParameters) => { + if (!config) { + throw new Error("config not loaded"); + } + + return createCollectionOffer(config, parameters); + } + }); + + return { + ...result, + createCollectionOffer: mutate, + createCollectionOfferAsync: mutateAsync + }; +} + +export { useCreateCollectionOffer }; diff --git a/packages/react/src/hooks/useCreateListing.test.ts b/packages/react/src/hooks/useCreateListing.test.ts new file mode 100644 index 000000000..5e06e952e --- /dev/null +++ b/packages/react/src/hooks/useCreateListing.test.ts @@ -0,0 +1,47 @@ +import { useAccount, useConnect, useDisconnect } from "@starknet-react/core"; +import { describe, expect, it } from "vitest"; + +import { accounts, defaultConnector, mintERC721 } from "@ark-project/test"; + +import { act, renderHook, waitFor } from "../../test/react"; +import { useCreateListing } from "./useCreateListing"; + +function useCreateListingWithConnect() { + return { + mutation: useCreateListing(), + account: useAccount(), + connect: useConnect(), + disconnect: useDisconnect() + }; +} + +describe("useCreateListing", () => { + it("default", async () => { + const { result } = renderHook(() => useCreateListingWithConnect()); + + await act(async () => { + await result.current.connect.connectAsync({ + connector: defaultConnector + }); + }); + + await act(async () => { + const seller = await defaultConnector.account(); + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + + await result.current.mutation.createListingAsync({ + account: seller, + brokerAddress: accounts.listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1000) + }); + }); + + await waitFor(() => expect(result.current.mutation.isSuccess).toBe(true)); + + await act(async () => { + await result.current.disconnect.disconnectAsync(); + }); + }, 20_000); +}); diff --git a/packages/react/src/hooks/useCreateListing.ts b/packages/react/src/hooks/useCreateListing.ts index bfce940e7..70592a56d 100644 --- a/packages/react/src/hooks/useCreateListing.ts +++ b/packages/react/src/hooks/useCreateListing.ts @@ -1,60 +1,37 @@ "use client"; -import { useState } from "react"; +import { useMutation } from "@tanstack/react-query"; -import { AccountInterface } from "starknet"; +import { createListing, CreateListingParameters } from "@ark-project/core"; -import { - Config, - createListing as createListingCore, - ListingV1 -} from "@ark-project/core"; - -import { Status } from "../types"; import { useConfig } from "./useConfig"; -export type CreateListingParameters = { - starknetAccount: AccountInterface; -} & ListingV1; +export type CreateListingResult = { + orderHash: bigint | undefined; + transactionHash: string; +}; function useCreateListing() { - const [status, setStatus] = useState("idle"); - const [response, setResponse] = useState(); const config = useConfig(); - async function createListing(parameters: CreateListingParameters) { - setStatus("loading"); - - try { - setStatus("loading"); - const orderHash = await createListingCore(config as Config, { - starknetAccount: parameters.starknetAccount, - order: { - startAmount: parameters.startAmount, - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId, - currencyAddress: - parameters.currencyAddress || config?.starknetCurrencyContract, - currencyChainId: - parameters.currencyChainId || config?.starknetProvider.getChainId(), - brokerId: parameters.brokerId, - startDate: parameters.startDate, - endDate: parameters.endDate - } as ListingV1, - approveInfo: { - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId - } - }); - setResponse(orderHash); - setStatus("success"); - } catch (error) { - console.error(error); - setStatus("error"); + const { mutate, mutateAsync, ...result } = useMutation({ + mutationKey: ["createListing"], + mutationFn: async (parameters: CreateListingParameters) => { + if (!config) { + throw new Error("config not loaded"); + } + + const result = await createListing(config, parameters); + + return result; } - } + }); - return { createListing, status, response }; + return { + ...result, + createListing: mutate, + createListingAsync: mutateAsync + }; } export { useCreateListing }; diff --git a/packages/react/src/hooks/useCreateOffer.test.ts b/packages/react/src/hooks/useCreateOffer.test.ts new file mode 100644 index 000000000..fb6bae038 --- /dev/null +++ b/packages/react/src/hooks/useCreateOffer.test.ts @@ -0,0 +1,59 @@ +import { useAccount, useConnect, useDisconnect } from "@starknet-react/core"; +import { describe, expect, it } from "vitest"; + +import { + accounts, + defaultConnector, + mintERC20, + mintERC721 +} from "@ark-project/test"; + +import { act, renderHook, waitFor } from "../../test/react"; +import useCreateOffer from "./useCreateOffer"; + +function useCreateOfferWithConnect() { + return { + mutation: useCreateOffer(), + account: useAccount(), + connect: useConnect(), + disconnect: useDisconnect() + }; +} + +describe("useCreateOffer", () => { + it("default", async () => { + const { seller } = accounts; + const { result } = renderHook(() => useCreateOfferWithConnect()); + + await act(async () => { + await result.current.connect.connectAsync({ + connector: defaultConnector + }); + }); + + await act(async () => { + const buyer = result.current.account.account; + + if (!buyer) { + throw new Error("Account not connected"); + } + + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + await mintERC20({ account: buyer, amount: 1000 }); + + await result.current.mutation.createOfferAsync({ + account: buyer, + brokerAddress: accounts.listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1000) + }); + }); + + await waitFor(() => expect(result.current.mutation.isSuccess).toBe(true)); + + await act(async () => { + await result.current.disconnect.disconnectAsync(); + }); + }, 10_000); +}); diff --git a/packages/react/src/hooks/useCreateOffer.ts b/packages/react/src/hooks/useCreateOffer.ts index 6b0e69f03..9d636f14f 100644 --- a/packages/react/src/hooks/useCreateOffer.ts +++ b/packages/react/src/hooks/useCreateOffer.ts @@ -1,67 +1,31 @@ "use client"; -import { useState } from "react"; +import { useMutation } from "@tanstack/react-query"; -import { AccountInterface, constants } from "starknet"; +import { createOffer, CreateOfferParameters } from "@ark-project/core"; -import { - Config, - createOffer as createOfferCore, - OfferV1 -} from "@ark-project/core"; - -import { Status } from "../types"; import { useConfig } from "./useConfig"; -export type CreateOfferParameters = { - starknetAccount: AccountInterface; - startAmount: bigint; - tokenAddress: string; - tokenId: bigint; - brokerId: string; - currencyAddress?: string; - currencyChainId?: constants.StarknetChainId; - startDate?: number; - endDate?: number; -}; - export default function useCreateOffer() { - const [status, setStatus] = useState("idle"); - const [response, setResponse] = useState(); const config = useConfig(); - async function createOffer(parameters: CreateOfferParameters) { - try { - setStatus("loading"); - const orderHash = await createOfferCore(config as Config, { - starknetAccount: parameters.starknetAccount, - offer: { - startAmount: parameters.startAmount, - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId, - currencyAddress: - parameters.currencyAddress || config?.starknetCurrencyContract, - currencyChainId: - parameters.currencyChainId || config?.starknetProvider.getChainId(), - brokerId: parameters.brokerId, - startDate: parameters.startDate, - endDate: parameters.endDate - } as OfferV1, - approveInfo: { - currencyAddress: - parameters.currencyAddress || - (config?.starknetCurrencyContract as string), - amount: parameters.startAmount - } - }); - setResponse(orderHash); - setStatus("success"); - } catch (error) { - setStatus("error"); - console.error(error); + const { mutate, mutateAsync, ...result } = useMutation({ + mutationKey: ["createOffer"], + mutationFn: async (parameters: CreateOfferParameters) => { + if (!config) { + throw new Error("config not loaded"); + } + + const result = await createOffer(config, parameters); + + return result; } - } + }); - return { createOffer, status, response }; + return { + ...result, + createOffer: mutate, + createOfferAsync: mutateAsync + }; } export { useCreateOffer }; diff --git a/packages/react/src/hooks/useDefaultCreatorFees.test.ts b/packages/react/src/hooks/useDefaultCreatorFees.test.ts new file mode 100644 index 000000000..4e9998a98 --- /dev/null +++ b/packages/react/src/hooks/useDefaultCreatorFees.test.ts @@ -0,0 +1,23 @@ +import { describe, expect, it } from "vitest"; + +import { renderHook, waitFor } from "../../test/react"; +import { useDefaultCreatorFees } from "./useDefaultCreatorFees"; + +describe("useDefaultCreatorFees", () => { + it("default", async () => { + const { result } = renderHook(useDefaultCreatorFees); + + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + + expect(result.current.data).toMatchInlineSnapshot(` + { + "creator": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", + "fees": { + "denominator": 1n, + "formatted": "0.00", + "numerator": 0n, + }, + } + `); + }); +}); diff --git a/packages/react/src/hooks/useDefaultCreatorFees.ts b/packages/react/src/hooks/useDefaultCreatorFees.ts new file mode 100644 index 000000000..06958e736 --- /dev/null +++ b/packages/react/src/hooks/useDefaultCreatorFees.ts @@ -0,0 +1,24 @@ +"use client"; + +import { useQuery } from "@tanstack/react-query"; + +import { getDefaultCreatorFees } from "@ark-project/core"; + +import { useConfig } from "./useConfig"; + +function useDefaultCreatorFees() { + const config = useConfig(); + + return useQuery({ + queryKey: ["getDefaultCreatorFees"], + queryFn: async () => { + if (!config) { + throw new Error("Config not found"); + } + + return getDefaultCreatorFees(config); + } + }); +} + +export { useDefaultCreatorFees }; diff --git a/packages/react/src/hooks/useFeesAmount.test.ts b/packages/react/src/hooks/useFeesAmount.test.ts new file mode 100644 index 000000000..f399fb4fa --- /dev/null +++ b/packages/react/src/hooks/useFeesAmount.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; + +import { accounts, mintERC721 } from "@ark-project/test"; + +import { renderHook, waitFor } from "../../test/react"; +import { useFeesAmount } from "./useFeesAmount"; + +describe("useFeesAmount", () => { + it("default", async () => { + const { seller, saleBroker, listingBroker } = accounts; + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + + const { result } = renderHook(() => + useFeesAmount({ + fulfillBroker: saleBroker.address, + listingBroker: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1000) + }) + ); + + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + + expect(result.current.data).toMatchInlineSnapshot(` + { + "ark": 0n, + "creator": 0n, + "fulfillBroker": 0n, + "listingBroker": 0n, + } + `); + }); +}); diff --git a/packages/react/src/hooks/useFeesAmount.ts b/packages/react/src/hooks/useFeesAmount.ts new file mode 100644 index 000000000..9c69c6182 --- /dev/null +++ b/packages/react/src/hooks/useFeesAmount.ts @@ -0,0 +1,52 @@ +"use client"; + +import { useQuery } from "@tanstack/react-query"; + +import { getFeesAmount } from "@ark-project/core"; + +import { useConfig } from "./useConfig"; + +interface UseFeesAmountProps { + fulfillBroker: string; + listingBroker: string; + tokenAddress: string; + tokenId: bigint; + amount: bigint; +} + +function useFeesAmount({ + fulfillBroker, + listingBroker, + tokenAddress, + tokenId, + amount +}: UseFeesAmountProps) { + const config = useConfig(); + + return useQuery({ + queryKey: [ + "getFeesAmount", + { + fulfillBroker, + listingBroker, + tokenAddress, + tokenId: tokenId.toString() + } + ], + queryFn: async () => { + if (!config) { + throw new Error("Config not found"); + } + + return getFeesAmount(config, { + fulfillBroker, + listingBroker, + nftAddress: tokenAddress, + nftTokenId: tokenId, + paymentAmount: amount + }); + } + }); +} + +export { useFeesAmount }; diff --git a/packages/react/src/hooks/useFulfillAuction.test.ts b/packages/react/src/hooks/useFulfillAuction.test.ts new file mode 100644 index 000000000..344563a8b --- /dev/null +++ b/packages/react/src/hooks/useFulfillAuction.test.ts @@ -0,0 +1,73 @@ +import { useAccount, useConnect, useDisconnect } from "@starknet-react/core"; +import { describe, expect, it } from "vitest"; + +import { createAuction, createOffer } from "@ark-project/core"; +import { + accounts, + defaultConnector, + mintERC20, + mintERC721 +} from "@ark-project/test"; +import { config } from "@ark-project/test/src/config"; + +import { act, renderHook, waitFor } from "../../test/react"; +import { useFulfillAuction } from "./useFulfillAuction"; + +function useCreateAuctionWithConnect() { + return { + fulfillAuction: useFulfillAuction(), + account: useAccount(), + connect: useConnect(), + disconnect: useDisconnect() + }; +} + +describe("useFulfillAuction", () => { + it("default", async () => { + const { seller, buyer, listingBroker, saleBroker } = accounts; + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + await mintERC20({ account: buyer, amount: 1000 }); + const { orderHash: relatedOrderHash } = await createAuction(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + startAmount: BigInt(1000), + endAmount: BigInt(2000) + }); + const { orderHash } = await createOffer(config, { + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1000) + }); + + const { result } = renderHook(useCreateAuctionWithConnect); + + await act(async () => { + await result.current.connect.connectAsync({ + connector: defaultConnector + }); + }); + + await act(async () => { + await result.current.fulfillAuction.fulfillAuctionAsync({ + account: seller, + brokerAddress: saleBroker.address, + orderHash: relatedOrderHash, + relatedOrderHash: orderHash, + tokenAddress, + tokenId + }); + }); + + await waitFor(() => + expect(result.current.fulfillAuction.isSuccess).toBe(true) + ); + + await act(async () => { + await result.current.disconnect.disconnectAsync(); + }); + }, 20_000); +}); diff --git a/packages/react/src/hooks/useFulfillAuction.ts b/packages/react/src/hooks/useFulfillAuction.ts index cf584d34a..625f53afd 100644 --- a/packages/react/src/hooks/useFulfillAuction.ts +++ b/packages/react/src/hooks/useFulfillAuction.ts @@ -1,50 +1,30 @@ "use client"; -import { useState } from "react"; +import { useMutation } from "@tanstack/react-query"; -import { AccountInterface } from "starknet"; +import { fulfillAuction, FulfillAuctionParameters } from "@ark-project/core"; -import { fulfillAuction } from "@ark-project/core"; -import { FulfillAuctionInfo } from "@ark-project/core/src/types"; - -import { Status } from "../types"; import { useConfig } from "./useConfig"; -export type FulfillAuctionParameters = FulfillAuctionInfo & { - starknetAccount: AccountInterface; -}; - function useFulfillAuction() { - const [status, setStatus] = useState("idle"); const config = useConfig(); - async function fulfill(parameters: FulfillAuctionParameters) { - if (!config) { - throw new Error("Invalid config."); - } + const { mutate, mutateAsync, ...result } = useMutation({ + mutationKey: ["fulfillAuction"], + mutationFn: async (parameters: FulfillAuctionParameters) => { + if (!config) { + throw new Error("config not loaded"); + } - setStatus("loading"); - - try { - await fulfillAuction(config, { - starknetAccount: parameters.starknetAccount, - fulfillAuctionInfo: { - orderHash: parameters.orderHash, - relatedOrderHash: parameters.relatedOrderHash, - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId, - brokerId: parameters.brokerId - } - }); - - setStatus("success"); - } catch (error) { - console.error(error); - setStatus("error"); + return fulfillAuction(config, parameters); } - } + }); - return { fulfill, status }; + return { + ...result, + fulfillAuction: mutate, + fulfillAuctionAsync: mutateAsync + }; } export { useFulfillAuction }; diff --git a/packages/react/src/hooks/useFulfillListing.test.ts b/packages/react/src/hooks/useFulfillListing.test.ts new file mode 100644 index 000000000..d2fd1d1a9 --- /dev/null +++ b/packages/react/src/hooks/useFulfillListing.test.ts @@ -0,0 +1,62 @@ +import { useAccount, useConnect, useDisconnect } from "@starknet-react/core"; +import { describe, expect, it } from "vitest"; + +import { createListing } from "@ark-project/core"; +import { accounts, defaultConnector, mintERC721 } from "@ark-project/test"; +import { config } from "@ark-project/test/src/config"; + +import { act, renderHook, waitFor } from "../../test/react"; +import { useCreateListing } from "./useCreateListing"; +import { useFulfillListing } from "./useFulfillListing"; + +function useCreateOfferWithConnect() { + return { + createListing: useCreateListing(), + fulfillListing: useFulfillListing(), + account: useAccount(), + connect: useConnect(), + disconnect: useDisconnect() + }; +} + +describe("useFulfillListing", () => { + it("default", async () => { + const { seller, buyer, listingBroker, saleBroker } = accounts; + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + // await mintERC20({ account: buyer, amount: 1000 }); + const { orderHash } = await createListing(config, { + account: seller, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1000) + }); + + const { result } = renderHook(useCreateOfferWithConnect); + + await act(async () => { + await result.current.connect.connectAsync({ + connector: defaultConnector + }); + }); + + await act(async () => { + await result.current.fulfillListing.fulfillListingAsync({ + account: buyer, + brokerAddress: saleBroker.address, + orderHash, + tokenAddress, + tokenId, + amount: BigInt(1000) + }); + }); + + await waitFor(() => + expect(result.current.fulfillListing.isSuccess).toBe(true) + ); + + await act(async () => { + await result.current.disconnect.disconnectAsync(); + }); + }, 10_000); +}); diff --git a/packages/react/src/hooks/useFulfillListing.ts b/packages/react/src/hooks/useFulfillListing.ts index 0fd20b189..7c1450054 100644 --- a/packages/react/src/hooks/useFulfillListing.ts +++ b/packages/react/src/hooks/useFulfillListing.ts @@ -1,54 +1,30 @@ "use client"; -import { useState } from "react"; +import { useMutation } from "@tanstack/react-query"; -import { AccountInterface } from "starknet"; +import { fulfillListing, FulfillListingParameters } from "@ark-project/core"; -import { - Config, - fulfillListing as fulfillListingCore -} from "@ark-project/core"; -import { FulfillListingInfo } from "@ark-project/core/src/types"; - -import { Status } from "../types"; import { useConfig } from "./useConfig"; -export type ApproveERC20Parameters = { - starknetAccount: AccountInterface; - startAmount: bigint; - currencyAddress?: string; -}; - -export type fulfillListingParameters = ApproveERC20Parameters & - FulfillListingInfo; - function useFulfillListing() { - const [status, setStatus] = useState("idle"); const config = useConfig(); - async function fulfillListing(parameters: fulfillListingParameters) { - try { - setStatus("loading"); - await fulfillListingCore(config as Config, { - starknetAccount: parameters.starknetAccount, - fulfillListingInfo: { - orderHash: parameters.orderHash, - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId, - brokerId: parameters.brokerId - } as FulfillListingInfo, - approveInfo: { - currencyAddress: (parameters.currencyAddress || - config?.starknetCurrencyContract) as string, - amount: BigInt(parameters.startAmount) - } - }); - setStatus("success"); - } catch (error) { - console.error(error); - setStatus("error"); + const { mutate, mutateAsync, ...result } = useMutation({ + mutationKey: ["fulfillListing"], + mutationFn: async (parameters: FulfillListingParameters) => { + if (!config) { + throw new Error("config not loaded"); + } + + return fulfillListing(config, parameters); } - } - return { fulfillListing, status }; + }); + + return { + ...result, + fulfillListing: mutate, + fulfillListingAsync: mutateAsync + }; } + export { useFulfillListing }; diff --git a/packages/react/src/hooks/useFulfillOffer.test.ts b/packages/react/src/hooks/useFulfillOffer.test.ts new file mode 100644 index 000000000..217765e89 --- /dev/null +++ b/packages/react/src/hooks/useFulfillOffer.test.ts @@ -0,0 +1,73 @@ +import { useAccount, useConnect, useDisconnect } from "@starknet-react/core"; +import { describe, expect, it } from "vitest"; + +import { + accounts, + defaultConnector, + mintERC20, + mintERC721 +} from "@ark-project/test"; + +import { act, renderHook, waitFor } from "../../test/react"; +import useCreateOffer from "./useCreateOffer"; +import { useFulfillOffer } from "./useFulfillOffer"; + +function useCreateOfferWithConnect() { + return { + createOffer: useCreateOffer(), + fulfillOffer: useFulfillOffer(), + account: useAccount(), + connect: useConnect(), + disconnect: useDisconnect() + }; +} + +describe("useFulfillOffer", () => { + it("default", async () => { + const { buyer, listingBroker, saleBroker } = accounts; + const { result } = renderHook(useCreateOfferWithConnect); + + await act(async () => { + await result.current.connect.connectAsync({ + connector: defaultConnector + }); + }); + + const seller = result.current.account.account; + + expect(seller).toBeDefined(); + + if (!seller) { + return; + } + + await act(async () => { + const { tokenId, tokenAddress } = await mintERC721({ account: seller }); + await mintERC20({ account: buyer, amount: 1000 }); + + const { orderHash } = await result.current.createOffer.createOfferAsync({ + account: buyer, + brokerAddress: listingBroker.address, + tokenAddress, + tokenId, + amount: BigInt(1000) + }); + + await result.current.fulfillOffer.fulfillOfferAsync({ + account: seller, + brokerAddress: saleBroker.address, + orderHash, + tokenAddress, + tokenId + }); + }); + + await waitFor(() => + expect(result.current.fulfillOffer.isSuccess).toBe(true) + ); + + await act(async () => { + await result.current.disconnect.disconnectAsync(); + }); + }, 10_000); +}); diff --git a/packages/react/src/hooks/useFulfillOffer.ts b/packages/react/src/hooks/useFulfillOffer.ts index 924f2b487..0cc41d1c9 100644 --- a/packages/react/src/hooks/useFulfillOffer.ts +++ b/packages/react/src/hooks/useFulfillOffer.ts @@ -1,46 +1,30 @@ "use client"; -import { useState } from "react"; +import { useMutation } from "@tanstack/react-query"; -import { AccountInterface } from "starknet"; +import { fulfillOffer, FulfillOfferParameters } from "@ark-project/core"; -import { Config, fulfillOffer as fulfillOfferCore } from "@ark-project/core"; -import { FulfillOfferInfo } from "@ark-project/core/src/types"; - -import { Status } from "../types"; import { useConfig } from "./useConfig"; -export type FulfillOfferParameters = { - starknetAccount: AccountInterface; -} & FulfillOfferInfo; - function useFulfillOffer() { - const [status, setStatus] = useState("idle"); const config = useConfig(); - async function fulfillOffer(parameters: FulfillOfferParameters) { - try { - setStatus("loading"); - await fulfillOfferCore(config as Config, { - starknetAccount: parameters.starknetAccount, - fulfillOfferInfo: { - orderHash: parameters.orderHash, - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId, - brokerId: parameters.brokerId - } as FulfillOfferInfo, - approveInfo: { - tokenAddress: parameters.tokenAddress, - tokenId: parameters.tokenId - } - }); - setStatus("success"); - } catch (error) { - console.error(error); - setStatus("error"); + const { mutate, mutateAsync, ...result } = useMutation({ + mutationKey: ["fulfillOffer"], + mutationFn: async (parameters: FulfillOfferParameters) => { + if (!config) { + throw new Error("config not loaded"); + } + + return fulfillOffer(config, parameters); } - } - return { fulfillOffer, status }; + }); + + return { + ...result, + fulfillOffer: mutate, + fulfillOfferAsync: mutateAsync + }; } export { useFulfillOffer }; diff --git a/packages/react/src/hooks/useOrderType.ts b/packages/react/src/hooks/useOrderType.ts index b55dd3b66..a1ec78015 100644 --- a/packages/react/src/hooks/useOrderType.ts +++ b/packages/react/src/hooks/useOrderType.ts @@ -1,7 +1,6 @@ "use client"; -import { useEffect, useState } from "react"; - +import { useQuery } from "@tanstack/react-query"; import { CairoCustomEnum } from "starknet"; import { getOrderType } from "@ark-project/core"; @@ -28,25 +27,21 @@ export function getTypeFromCairoCustomEnum(cairoCustomEnum: CairoCustomEnum) { } function useOrderType({ orderHash }: { orderHash: bigint }) { - const [type, setType] = useState(null); const config = useConfig(); - useEffect(() => { - const run = async () => { + return useQuery({ + queryKey: ["orderType", orderHash], + queryFn: async () => { if (!config) { - return; + throw new Error("Config not found"); } const orderTypeCairo = await getOrderType(config, { orderHash }); const orderType = getTypeFromCairoCustomEnum(orderTypeCairo.orderType); - setType(orderType); - }; - - run(); - }, [config, orderHash]); - - return type; + return orderType; + } + }); } export { useOrderType }; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index a234113be..915ef8847 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -1,2 +1,3 @@ -export * from "./components"; export * from "./hooks"; +export * from "./components"; +export { QueryClient as ArkQueryClient, QueryClientProvider as ArkQueryClientProvider } from "@tanstack/react-query"; \ No newline at end of file diff --git a/packages/react/test/react.tsx b/packages/react/test/react.tsx new file mode 100644 index 000000000..9dde58147 --- /dev/null +++ b/packages/react/test/react.tsx @@ -0,0 +1,116 @@ +import React from "react"; + +import { devnet, mainnet } from "@starknet-react/chains"; +import { + jsonRpcProvider, + MockConnectorOptions, + StarknetConfig as OgStarknetConfig +} from "@starknet-react/core"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { + render, + renderHook, + RenderHookOptions, + RenderOptions, + RenderResult +} from "@testing-library/react"; + +import { config, defaultConnector } from "@ark-project/test"; + +import { ArkProvider } from "../src/components/ArkProvider"; + +function rpc() { + return { + nodeUrl: devnet.rpcUrls.public.http[0] + }; +} + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + gcTime: 0, + retry: false + } + } +}); + +function StarknetConfig({ + children +}: { + children: React.ReactNode; + connectorOptions?: Partial; +}) { + const chains = [devnet, mainnet]; + const provider = jsonRpcProvider({ rpc }); + const connectors = [defaultConnector]; + + // defaultConnector.options = { + // ...defaultConnector.options, + // ...connectorOptions + // }; + + const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false + } + } + }); + + return ( + + {children} + + ); +} + +function customRender( + ui: React.ReactElement, + options: Omit & { + connectorOptions?: Partial; + } = {} +): RenderResult { + const { connectorOptions, ...renderOptions } = options; + queryClient.clear(); + + return render(ui, { + wrapper: ({ children }) => ( + + + {children} + + + ), + ...renderOptions + }); +} + +function customRenderHook( + render: () => RenderResult, + options: Omit, "wrapper"> & { + connectorOptions?: Partial; + } = {} +) { + const { connectorOptions, hydrate, ...renderOptions } = options; + queryClient.clear(); + + return renderHook(render, { + wrapper: ({ children }) => ( + + + {children} + + + ), + hydrate: hydrate as false | undefined, + ...renderOptions + }); +} + +export * from "@testing-library/react"; +export { customRender as render, customRenderHook as renderHook }; diff --git a/packages/react/test/setup.ts b/packages/react/test/setup.ts new file mode 100644 index 000000000..0c422eddf --- /dev/null +++ b/packages/react/test/setup.ts @@ -0,0 +1,3 @@ +import * as dotenv from "dotenv"; + +dotenv.config({ path: "../../.env" }); diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json index 140b3def0..dbf587c5b 100644 --- a/packages/react/tsconfig.json +++ b/packages/react/tsconfig.json @@ -1,19 +1,12 @@ { "extends": "@ark-project/typescript-config/react-library.json", - "include": [ - "." - ], - "exclude": [ - "dist", - "build", - "node_modules" - ], + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["dist", "build", "node_modules"], "compilerOptions": { "jsx": "react", "declarationDir": "types", "sourceMap": true, "outDir": "dist", - "allowSyntheticDefaultImports": true, - "emitDeclarationOnly": true + "allowSyntheticDefaultImports": true } -} \ No newline at end of file +} diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts new file mode 100644 index 000000000..00cde9e95 --- /dev/null +++ b/packages/react/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + globals: true, + environment: "jsdom", + setupFiles: ["./test/setup.ts"] + } +}); diff --git a/packages/test/.eslintrc.js b/packages/test/.eslintrc.js new file mode 100644 index 000000000..b5cf4b054 --- /dev/null +++ b/packages/test/.eslintrc.js @@ -0,0 +1,14 @@ +/** @type {import("eslint").Linter.Config} */ +module.exports = { + root: true, + env: { + browser: true, + es6: true, + node: false + }, + extends: ["@ark-project/eslint-config/react-internal.js"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true + } +}; diff --git a/packages/test/package.json b/packages/test/package.json new file mode 100644 index 000000000..d81c914f2 --- /dev/null +++ b/packages/test/package.json @@ -0,0 +1,35 @@ +{ + "name": "@ark-project/test", + "version": "1.0.0", + "private": true, + "description": "Test utils for @ark-project", + "type": "module", + "main": "./src/exports/index.ts", + "types": "./src/exports/index.ts", + "scripts": { + "clean": "rm -rf .turbo dist node_modules tsconfig.tsbuildinfo", + "lint": "eslint --ext .ts,.tsx .", + "lint:fix": "eslint --ext .ts,.tsx . --fix", + "test": "vitest", + "typecheck": "tsc --noEmit" + }, + "devDependencies": { + "@ark-project/eslint-config": "workspace:*", + "@ark-project/typescript-config": "workspace:*", + "@starknet-react/chains": "^3.1.2", + "@starknet-react/core": "^3.7.2", + "@tanstack/react-query": "^5.68.0", + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.2.0", + "@testing-library/react-hooks": "^8.0.1", + "@types/react": "^18.3.18", + "dotenv": "^16.4.7", + "jest-environment-jsdom": "^29.7.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-test-renderer": "^18.3.1", + "starknet": "^6.23.1", + "typescript": "^5.8.2" + } +} diff --git a/packages/test/src/accounts.ts b/packages/test/src/accounts.ts new file mode 100644 index 000000000..b2b71e367 --- /dev/null +++ b/packages/test/src/accounts.ts @@ -0,0 +1,115 @@ +import { MockConnector } from "@starknet-react/core"; +import { Account, AccountInterface, ProviderInterface } from "starknet"; + +import { config } from "./config.js"; + +function fetchAccount( + provider: ProviderInterface, + address: string | undefined, + privateKey: string | undefined, + accountName: string +): AccountInterface { + if (!address || !privateKey) { + throw new Error( + `Missing address or private key for account: ${accountName}` + ); + } + try { + return new Account(provider, address, privateKey); + } catch (error) { + throw new Error(`Error creating account for ${accountName}: ${error}`); + } +} + +export function getAccounts(): { + arkDefaultFeesReceiver: AccountInterface; + arkSetbyAdminCollectionReceiver: AccountInterface; + arkCollection2981Receiver: AccountInterface; + admin: AccountInterface; + listingBroker: AccountInterface; + saleBroker: AccountInterface; + offerer: AccountInterface; + fulfiller: AccountInterface; + seller: AccountInterface; + buyer: AccountInterface; +} { + return { + arkDefaultFeesReceiver: fetchAccount( + config.starknetProvider, + process.env.STARKNET_ARK_RECEIVER_ADDRESS, + process.env.STARKNET_ARK_RECEIVER_PRIVATE_KEY, + "arkDefaultFeesReceiver" + ), + arkSetbyAdminCollectionReceiver: fetchAccount( + config.starknetProvider, + process.env.STARKNET_ARK_COLLECTION_RECEIVER_ADDRESS, + process.env.STARKNET_ARK_COLLECTION_RECEIVER_PRIVATE_KEY, + "arkSetbyAdminCollectionReceiver" + ), + arkCollection2981Receiver: fetchAccount( + config.starknetProvider, + process.env.STARKNET_ARK_COLLECTION_2981_RECEIVER_ADDRESS, + process.env.STARKNET_ARK_COLLECTION_2981_RECEIVER_PRIVATE_KEY, + "arkCollection2981Receiver" + ), + admin: fetchAccount( + config.starknetProvider, + process.env.STARKNET_ADMIN_ADDRESS_DEV, + process.env.STARKNET_ADMIN_PRIVATE_KEY_DEV, + "admin" + ), + listingBroker: fetchAccount( + config.starknetProvider, + process.env.STARKNET_LISTING_BROKER_ACCOUNT_ADDRESS, + process.env.STARKNET_LISTING_BROKER_ACCOUNT_PRIVATE_KEY, + "listingBroker" + ), + saleBroker: fetchAccount( + config.starknetProvider, + process.env.STARKNET_SALE_BROKER_ACCOUNT_ADDRESS, + process.env.STARKNET_SALE_BROKER_ACCOUNT_PRIVATE_KEY, + "saleBroker" + ), + offerer: fetchAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY, + "offerer" + ), + fulfiller: fetchAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT2_ADDRESS, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY, + "fulfiller" + ), + seller: fetchAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY, + "seller" + ), + buyer: fetchAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT2_ADDRESS, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY, + "buyer" + ) + }; +} + +export function getDefaultConnector() { + const accounts = getAccounts(); + const accountsArray = Object.values(accounts); + + return new MockConnector({ + accounts: { + mainnet: accountsArray, + goerli: accountsArray + }, + options: { + id: "mock", + name: "Mock Connector", + icon: { dark: "https://example.com/icon.png" } + } + }); +} diff --git a/packages/test/src/config.ts b/packages/test/src/config.ts new file mode 100644 index 000000000..15c12e622 --- /dev/null +++ b/packages/test/src/config.ts @@ -0,0 +1,10 @@ +import contracts from "../../../contracts.dev.json"; +import { createConfig } from "../../core/src/createConfig.js"; + +const config = createConfig({ + starknetNetwork: "dev", + starknetExecutorContract: contracts.executor, + starknetCurrencyContract: contracts.eth +}); + +export { config }; diff --git a/packages/test/src/exports/index.ts b/packages/test/src/exports/index.ts new file mode 100644 index 000000000..bc2c98b7e --- /dev/null +++ b/packages/test/src/exports/index.ts @@ -0,0 +1,3 @@ +export * from "../accounts.js"; +export { config } from "../config.js"; +export { getBalance, mintERC20, mintERC721 } from "../utils.js"; diff --git a/packages/test/src/setup.ts b/packages/test/src/setup.ts new file mode 100644 index 000000000..c5693c9f5 --- /dev/null +++ b/packages/test/src/setup.ts @@ -0,0 +1,4 @@ +import * as dotenv from "dotenv"; + +// eslint-disable-next-line no-undef +dotenv.config({ path: `${__dirname}/../../../.env` }); diff --git a/packages/test/src/utils.ts b/packages/test/src/utils.ts new file mode 100644 index 000000000..ffd8b35b2 --- /dev/null +++ b/packages/test/src/utils.ts @@ -0,0 +1,144 @@ +import { + Account, + AccountInterface, + cairo, + CallData, + Contract, + type Call +} from "starknet"; + +import contracts from "../../../contracts.dev.json"; +import { config } from "./config.js"; + +export async function wait(time: number) { + return new Promise((res) => setTimeout(res, time)); +} + +const mintERC20ABI = [ + { + type: "function", + name: "mint", + inputs: [ + { + name: "recipient", + type: "core::starknet::contract_address::ContractAddress" + }, + { + name: "amount", + type: "core::integer::u256" + } + ], + outputs: [], + state_mutability: "external" + } +]; + +export async function mintERC20({ + account, + amount = 1000 +}: { + account: Account | AccountInterface; + amount: number; +}) { + const mintERC20Call: Call = { + contractAddress: config.starknetCurrencyContract, + entrypoint: "mint", + calldata: CallData.compile([account.address, cairo.uint256(amount)]) + }; + + const result = await account.execute(mintERC20Call, [mintERC20ABI]); + + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); + + return { + transactionHash: result.transaction_hash + }; +} + +const mintERC721ABI = [ + { + type: "function", + name: "mint", + inputs: [ + { + name: "recipient", + type: "core::starknet::contract_address::ContractAddress" + }, + { name: "token_uri", type: "core::felt252" } + ], + outputs: [], + state_mutability: "external" + }, + { + type: "function", + name: "get_current_token_id", + inputs: [], + outputs: [{ type: "core::felt252" }], + state_mutability: "view" + } +] as const; + +export async function mintERC721({ + account +}: { + account: Account | AccountInterface; +}) { + const contract = new Contract( + mintERC721ABI, + contracts.nftContract, + config.starknetProvider + ).typedv2(mintERC721ABI); + const tokenId = BigInt(await contract.get_current_token_id()); + const mintCall: Call = { + contractAddress: contracts.nftContract, + entrypoint: "mint", + calldata: CallData.compile({ + recipient: account.address, + token_uri: `https://api.everai.xyz/m/1` + }) + }; + + const { transaction_hash } = await account.execute(mintCall, [mintERC721ABI]); + + await config.starknetProvider.waitForTransaction(transaction_hash, { + retryInterval: 1000 + }); + + return { + tokenId, + tokenAddress: contracts.nftContract + }; +} + +const balanceOfERC20ABI = [ + { + type: "function", + name: "balanceOf", + inputs: [ + { + name: "account", + type: "core::starknet::contract_address::ContractAddress" + } + ], + outputs: [{ type: "core::integer::u256" }], + state_mutability: "view" + } +] as const; + +export async function getBalance({ + account +}: { + account: Account | AccountInterface; +}) { + const contract = new Contract( + balanceOfERC20ABI, + config.starknetCurrencyContract, + config.starknetProvider + ).typedv2(balanceOfERC20ABI); + + const balance = await contract.balanceOf(account.address); + + return balance as bigint; +} diff --git a/packages/test/tsconfig.json b/packages/test/tsconfig.json new file mode 100644 index 000000000..23cbe065f --- /dev/null +++ b/packages/test/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@ark-project/typescript-config/base.json", + "include": ["src/**/*.ts"], + "exclude": [], + "compilerOptions": { + "jsx": "react", + "lib": ["dom", "esnext"], + "module": "esnext", + "esModuleInterop": true + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dba265ce9..99ea8eeda 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,6 @@ importers: '@ark-project/typescript-config': specifier: workspace:* version: link:packages/typescript-config - '@changesets/cli': - specifier: ^2.27.1 - version: 2.27.7 '@ianvs/prettier-plugin-sort-imports': specifier: ^4.1.1 version: 4.3.1(prettier@3.3.3) @@ -38,12 +35,22 @@ importers: prettier-plugin-sort-imports: specifier: ^1.8.1 version: 1.8.6(typescript@5.5.4) - turbo: - specifier: ^1.13.3 - version: 1.13.4 typescript: specifier: ^5.0.0 version: 5.5.4 + devDependencies: + '@changesets/cli': + specifier: ^2.27.9 + version: 2.27.9 + patch-package: + specifier: ^8.0.0 + version: 8.0.0 + postinstall-postinstall: + specifier: ^2.1.0 + version: 2.1.0 + turbo: + specifier: ^2.1.3 + version: 2.1.3 examples/core: dependencies: @@ -58,7 +65,7 @@ importers: version: 6.11.0 ts-node: specifier: ^10.9.1 - version: 10.9.2(@types/node@20.16.1)(typescript@5.5.4) + version: 10.9.2(@types/node@22.13.10)(typescript@5.5.4) typescript: specifier: ^5.0.0 version: 5.5.4 @@ -68,7 +75,7 @@ importers: devDependencies: '@types/bun': specifier: latest - version: 1.1.7 + version: 1.1.11 packages/core: dependencies: @@ -76,21 +83,21 @@ importers: specifier: ^0.3.0 version: 0.3.0 starknet: - specifier: ^6.9.0 - version: 6.11.0 + specifier: ^6.23.1 + version: 6.23.1 viem: specifier: '>=0.3.35' - version: 2.20.0(typescript@5.5.4)(zod@3.23.8) + version: 2.20.0(typescript@5.5.4)(zod@3.24.2) devDependencies: '@ark-project/eslint-config': specifier: workspace:* version: link:../eslint-config + '@ark-project/test': + specifier: workspace:* + version: link:../test '@ark-project/typescript-config': specifier: workspace:* version: link:../typescript-config - '@types/jest': - specifier: ^29.5.5 - version: 29.5.12 '@types/node': specifier: ^20.10.7 version: 20.16.1 @@ -106,36 +113,33 @@ importers: eslint-plugin-mocha: specifier: ^10.2.0 version: 10.5.0(eslint@8.57.0) - jest: - specifier: ^29.7.0 - version: 29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) mocha: specifier: ^10.3.0 version: 10.7.3 nodemon: specifier: ^3.0.2 version: 3.1.4 - ts-jest: - specifier: ^29.1.1 - version: 29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(esbuild@0.20.2)(jest@29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: ^10.9.1 version: 10.9.2(@types/node@20.16.1)(typescript@5.5.4) tsup: specifier: ^8.0.1 - version: 8.2.4(tsx@4.17.0)(typescript@5.5.4) + version: 8.2.4(postcss@8.5.3)(tsx@4.17.0)(typescript@5.5.4)(yaml@2.5.1) tsx: specifier: ^4.11.0 version: 4.17.0 typescript: specifier: ^5.2.2 version: 5.5.4 + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@20.16.1)(jsdom@20.0.3) packages/deployer: dependencies: commander: - specifier: ^11.1.0 - version: 11.1.0 + specifier: ^12.1.0 + version: 12.1.0 dotenv: specifier: ^16.3.1 version: 16.4.5 @@ -152,9 +156,6 @@ importers: specifier: ^3.22.4 version: 3.23.8 devDependencies: - '@ark-project/core': - specifier: workspace:* - version: link:../core '@ark-project/eslint-config': specifier: workspace:* version: link:../eslint-config @@ -162,8 +163,8 @@ importers: specifier: workspace:* version: link:../typescript-config '@types/node': - specifier: ^20.10.7 - version: 20.16.1 + specifier: ^22.5.4 + version: 22.5.5 tsx: specifier: ^4.11.0 version: 4.17.0 @@ -190,8 +191,8 @@ importers: specifier: ^9.0.0 version: 9.1.0(eslint@8.57.0) eslint-config-turbo: - specifier: ^1.10.12 - version: 1.13.4(eslint@8.57.0) + specifier: ^2.1.2 + version: 2.1.2(eslint@8.57.0) eslint-plugin-only-warn: specifier: ^1.1.0 version: 1.1.0 @@ -205,47 +206,137 @@ importers: specifier: workspace:* version: link:../core '@starknet-react/chains': - specifier: ^0.1.7 - version: 0.1.7 + specifier: ^3.1.2 + version: 3.1.2 '@starknet-react/core': - specifier: ^2.8.1 - version: 2.9.0(get-starknet-core@3.3.3(starknet@6.11.0))(react@18.3.1)(starknet@6.11.0) + specifier: ^3.7.2 + version: 3.7.2(get-starknet-core@3.3.5(starknet@6.23.1))(react@18.3.1)(starknet@6.23.1)(typescript@5.8.2) + '@tanstack/react-query': + specifier: ^5.68.0 + version: 5.68.0(react@18.3.1) get-starknet-core: - specifier: ^3.3.0 - version: 3.3.3(starknet@6.11.0) + specifier: ^3.3.5 + version: 3.3.5(starknet@6.23.1) react: - specifier: ^18 + specifier: ^18.3.1 version: 18.3.1 react-dom: - specifier: ^18 + specifier: ^18.3.1 version: 18.3.1(react@18.3.1) starknet: - specifier: ^6.9.0 - version: 6.11.0 + specifier: ^6.23.1 + version: 6.23.1 devDependencies: '@ark-project/eslint-config': specifier: workspace:* version: link:../eslint-config + '@ark-project/test': + specifier: workspace:* + version: link:../test '@ark-project/typescript-config': specifier: workspace:* version: link:../typescript-config + '@testing-library/dom': + specifier: ^10.4.0 + version: 10.4.0 + '@testing-library/jest-dom': + specifier: ^6.6.3 + version: 6.6.3 + '@testing-library/react': + specifier: ^16.2.0 + version: 16.2.0(@testing-library/dom@10.4.0)(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@testing-library/react-hooks': + specifier: ^8.0.1 + version: 8.0.1(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react-test-renderer@18.3.1(react@18.3.1))(react@18.3.1) '@types/react': - specifier: ^18 - version: 18.3.4 + specifier: ^18.3.18 + version: 18.3.18 + dotenv: + specifier: ^16.4.7 + version: 16.4.7 + jest-environment-jsdom: + specifier: ^29.7.0 + version: 29.7.0 nodemon: - specifier: ^3.0.2 - version: 3.1.4 + specifier: ^3.1.9 + version: 3.1.9 + react-test-renderer: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) typescript: - specifier: ^5.3.3 - version: 5.5.4 + specifier: ^5.8.2 + version: 5.8.2 + vitest: + specifier: ^2.1.9 + version: 2.1.9(@types/node@22.13.10)(jsdom@20.0.3) + + packages/test: + devDependencies: + '@ark-project/eslint-config': + specifier: workspace:* + version: link:../eslint-config + '@ark-project/typescript-config': + specifier: workspace:* + version: link:../typescript-config + '@starknet-react/chains': + specifier: ^3.1.2 + version: 3.1.2 + '@starknet-react/core': + specifier: ^3.7.2 + version: 3.7.2(get-starknet-core@4.0.0)(react@18.3.1)(starknet@6.23.1)(typescript@5.8.2) + '@tanstack/react-query': + specifier: ^5.68.0 + version: 5.68.0(react@18.3.1) + '@testing-library/dom': + specifier: ^10.4.0 + version: 10.4.0 + '@testing-library/jest-dom': + specifier: ^6.6.3 + version: 6.6.3 + '@testing-library/react': + specifier: ^16.2.0 + version: 16.2.0(@testing-library/dom@10.4.0)(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@testing-library/react-hooks': + specifier: ^8.0.1 + version: 8.0.1(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react-test-renderer@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react': + specifier: ^18.3.18 + version: 18.3.18 + dotenv: + specifier: ^16.4.7 + version: 16.4.7 + jest-environment-jsdom: + specifier: ^29.7.0 + version: 29.7.0 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-test-renderer: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + starknet: + specifier: ^6.23.1 + version: 6.23.1 + typescript: + specifier: ^5.8.2 + version: 5.8.2 packages/typescript-config: {} packages: + '@adobe/css-tools@4.4.2': + resolution: {integrity: sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==} + '@adraffy/ens-normalize@1.10.0': resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -254,14 +345,26 @@ packages: resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.25.4': resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.26.8': + resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + engines: {node: '>=6.9.0'} + '@babel/core@7.25.2': resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} engines: {node: '>=6.9.0'} + '@babel/core@7.26.10': + resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} + engines: {node: '>=6.9.0'} + '@babel/eslint-parser@7.25.1': resolution: {integrity: sha512-Y956ghgTT4j7rKesabkh5WeqgSFZVFwaPR0IWFm7KFHFmmJ4afbG49SmfW4S+GyRPx0Dy5jxEWA5t0rpxfElWg==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} @@ -273,22 +376,40 @@ packages: resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==} engines: {node: '>=6.9.0'} + '@babel/generator@7.26.10': + resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.25.2': resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.26.5': + resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.24.7': resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.25.2': resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.24.8': - resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.26.5': + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} engines: {node: '>=6.9.0'} '@babel/helper-simple-access@7.24.7': @@ -299,18 +420,34 @@ packages: resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.7': resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.24.8': resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + '@babel/helpers@7.25.0': resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.26.10': + resolution: {integrity: sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==} + engines: {node: '>=6.9.0'} + '@babel/highlight@7.24.7': resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} @@ -320,6 +457,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.26.10': + resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-syntax-async-generators@7.8.4': resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -341,8 +483,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.24.7': - resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + '@babel/plugin-syntax-import-attributes@7.26.0': + resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -357,8 +499,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.24.7': - resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -405,8 +547,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.25.4': - resolution: {integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==} + '@babel/plugin-syntax-typescript@7.25.9': + resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -415,66 +557,82 @@ packages: resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.26.10': + resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.25.0': resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} engines: {node: '>=6.9.0'} + '@babel/template@7.26.9': + resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.25.4': resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.26.10': + resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==} + engines: {node: '>=6.9.0'} + '@babel/types@7.25.4': resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==} engines: {node: '>=6.9.0'} + '@babel/types@7.26.10': + resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@changesets/apply-release-plan@7.0.4': - resolution: {integrity: sha512-HLFwhKWayKinWAul0Vj+76jVx1Pc2v55MGPVjZ924Y/ROeSsBMFutv9heHmCUj48lJyRfOTJG5+ar+29FUky/A==} + '@changesets/apply-release-plan@7.0.5': + resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==} - '@changesets/assemble-release-plan@6.0.3': - resolution: {integrity: sha512-bLNh9/Lgl1VwkjWZTq8JmRqH+hj7/Yzfz0jsQ/zJJ+FTmVqmqPj3szeKOri8O/hEM8JmHW019vh2gTO9iq5Cuw==} + '@changesets/assemble-release-plan@6.0.4': + resolution: {integrity: sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==} '@changesets/changelog-git@0.2.0': resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} - '@changesets/cli@2.27.7': - resolution: {integrity: sha512-6lr8JltiiXPIjDeYg4iM2MeePP6VN/JkmqBsVA5XRiy01hGS3y629LtSDvKcycj/w/5Eur1rEwby/MjcYS+e2A==} + '@changesets/cli@2.27.9': + resolution: {integrity: sha512-q42a/ZbDnxPpCb5Wkm6tMVIxgeI9C/bexntzTeCFBrQEdpisQqk8kCHllYZMDjYtEc1ZzumbMJAG8H0Z4rdvjg==} hasBin: true - '@changesets/config@3.0.2': - resolution: {integrity: sha512-cdEhS4t8woKCX2M8AotcV2BOWnBp09sqICxKapgLHf9m5KdENpWjyrFNMjkLqGJtUys9U+w93OxWT0czorVDfw==} + '@changesets/config@3.0.3': + resolution: {integrity: sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} - '@changesets/get-dependents-graph@2.1.1': - resolution: {integrity: sha512-LRFjjvigBSzfnPU2n/AhFsuWR5DK++1x47aq6qZ8dzYsPtS/I5mNhIGAS68IAxh1xjO9BTtz55FwefhANZ+FCA==} + '@changesets/get-dependents-graph@2.1.2': + resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} - '@changesets/get-release-plan@4.0.3': - resolution: {integrity: sha512-6PLgvOIwTSdJPTtpdcr3sLtGatT+Jr22+cQwEBJBy6wP0rjB4yJ9lv583J9fVpn1bfQlBkDa8JxbS2g/n9lIyA==} + '@changesets/get-release-plan@4.0.4': + resolution: {integrity: sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} - '@changesets/git@3.0.0': - resolution: {integrity: sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==} + '@changesets/git@3.0.1': + resolution: {integrity: sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==} - '@changesets/logger@0.1.0': - resolution: {integrity: sha512-pBrJm4CQm9VqFVwWnSqKEfsS2ESnwqwH+xR7jETxIErZcfd1u2zBSqrHbRHR7xjhSgep9x2PSKFKY//FAshA3g==} + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} '@changesets/parse@0.4.0': resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} - '@changesets/pre@2.0.0': - resolution: {integrity: sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==} + '@changesets/pre@2.0.1': + resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} - '@changesets/read@0.6.0': - resolution: {integrity: sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==} + '@changesets/read@0.6.1': + resolution: {integrity: sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==} - '@changesets/should-skip-package@0.1.0': - resolution: {integrity: sha512-FxG6Mhjw7yFStlSM7Z0Gmg3RiyQ98d/9VpQAZ3Fzr59dCOM9G6ZdYbjiSAt0XtFr9JR5U2tBaJWPjrkGGc618g==} + '@changesets/should-skip-package@0.1.1': + resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} '@changesets/types@4.1.0': resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} @@ -482,8 +640,8 @@ packages: '@changesets/types@6.0.0': resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} - '@changesets/write@0.3.1': - resolution: {integrity: sha512-SyGtMXzH3qFqlHKcvFY2eX+6b0NGiFcNav8AFsYwy5l8hejOeoeTDemu5Yjmke2V5jpzY+pBvM0vCCQ3gdZpfw==} + '@changesets/write@0.3.2': + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} @@ -502,6 +660,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.23.1': resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} engines: {node: '>=18'} @@ -514,6 +678,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.23.1': resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} engines: {node: '>=18'} @@ -526,6 +696,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.23.1': resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} engines: {node: '>=18'} @@ -538,6 +714,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.23.1': resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} engines: {node: '>=18'} @@ -550,6 +732,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.23.1': resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} engines: {node: '>=18'} @@ -562,6 +750,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.23.1': resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} engines: {node: '>=18'} @@ -574,6 +768,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.23.1': resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} engines: {node: '>=18'} @@ -586,6 +786,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.23.1': resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} engines: {node: '>=18'} @@ -598,6 +804,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.23.1': resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} engines: {node: '>=18'} @@ -610,6 +822,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.23.1': resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} engines: {node: '>=18'} @@ -622,6 +840,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.23.1': resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} engines: {node: '>=18'} @@ -634,6 +858,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.23.1': resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} engines: {node: '>=18'} @@ -646,6 +876,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.23.1': resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} engines: {node: '>=18'} @@ -658,6 +894,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.23.1': resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} engines: {node: '>=18'} @@ -670,6 +912,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.23.1': resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} engines: {node: '>=18'} @@ -682,6 +930,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.23.1': resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} engines: {node: '>=18'} @@ -694,6 +948,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.23.1': resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} engines: {node: '>=18'} @@ -706,6 +966,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.23.1': resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} engines: {node: '>=18'} @@ -724,6 +990,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.23.1': resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} engines: {node: '>=18'} @@ -736,6 +1008,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.23.1': resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} engines: {node: '>=18'} @@ -748,6 +1026,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.23.1': resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} engines: {node: '>=18'} @@ -760,6 +1044,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.23.1': resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} engines: {node: '>=18'} @@ -772,6 +1062,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.23.1': resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} engines: {node: '>=18'} @@ -900,6 +1196,10 @@ packages: resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -950,6 +1250,14 @@ packages: '@noble/curves@1.4.2': resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + '@noble/curves@1.7.0': + resolution: {integrity: sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} + '@noble/hashes@1.3.2': resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} engines: {node: '>= 16'} @@ -962,6 +1270,14 @@ packages: resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} engines: {node: '>= 16'} + '@noble/hashes@1.6.0': + resolution: {integrity: sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1027,99 +1343,209 @@ packages: cpu: [arm] os: [android] + '@rollup/rollup-android-arm-eabi@4.36.0': + resolution: {integrity: sha512-jgrXjjcEwN6XpZXL0HUeOVGfjXhPyxAbbhD0BlXUB+abTOpbPiN5Wb3kOT7yb+uEtATNYF5x5gIfwutmuBA26w==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.21.0': resolution: {integrity: sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==} cpu: [arm64] os: [android] + '@rollup/rollup-android-arm64@4.36.0': + resolution: {integrity: sha512-NyfuLvdPdNUfUNeYKUwPwKsE5SXa2J6bCt2LdB/N+AxShnkpiczi3tcLJrm5mA+eqpy0HmaIY9F6XCa32N5yzg==} + cpu: [arm64] + os: [android] + '@rollup/rollup-darwin-arm64@4.21.0': resolution: {integrity: sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==} cpu: [arm64] os: [darwin] + '@rollup/rollup-darwin-arm64@4.36.0': + resolution: {integrity: sha512-JQ1Jk5G4bGrD4pWJQzWsD8I1n1mgPXq33+/vP4sk8j/z/C2siRuxZtaUA7yMTf71TCZTZl/4e1bfzwUmFb3+rw==} + cpu: [arm64] + os: [darwin] + '@rollup/rollup-darwin-x64@4.21.0': resolution: {integrity: sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==} cpu: [x64] os: [darwin] + '@rollup/rollup-darwin-x64@4.36.0': + resolution: {integrity: sha512-6c6wMZa1lrtiRsbDziCmjE53YbTkxMYhhnWnSW8R/yqsM7a6mSJ3uAVT0t8Y/DGt7gxUWYuFM4bwWk9XCJrFKA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.36.0': + resolution: {integrity: sha512-KXVsijKeJXOl8QzXTsA+sHVDsFOmMCdBRgFmBb+mfEb/7geR7+C8ypAml4fquUt14ZyVXaw2o1FWhqAfOvA4sg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.36.0': + resolution: {integrity: sha512-dVeWq1ebbvByI+ndz4IJcD4a09RJgRYmLccwlQ8bPd4olz3Y213uf1iwvc7ZaxNn2ab7bjc08PrtBgMu6nb4pQ==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.21.0': resolution: {integrity: sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==} cpu: [arm] os: [linux] + '@rollup/rollup-linux-arm-gnueabihf@4.36.0': + resolution: {integrity: sha512-bvXVU42mOVcF4le6XSjscdXjqx8okv4n5vmwgzcmtvFdifQ5U4dXFYaCB87namDRKlUL9ybVtLQ9ztnawaSzvg==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm-musleabihf@4.21.0': resolution: {integrity: sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==} cpu: [arm] os: [linux] + '@rollup/rollup-linux-arm-musleabihf@4.36.0': + resolution: {integrity: sha512-JFIQrDJYrxOnyDQGYkqnNBtjDwTgbasdbUiQvcU8JmGDfValfH1lNpng+4FWlhaVIR4KPkeddYjsVVbmJYvDcg==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.21.0': resolution: {integrity: sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==} cpu: [arm64] os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.36.0': + resolution: {integrity: sha512-KqjYVh3oM1bj//5X7k79PSCZ6CvaVzb7Qs7VMWS+SlWB5M8p3FqufLP9VNp4CazJ0CsPDLwVD9r3vX7Ci4J56A==} + cpu: [arm64] + os: [linux] + '@rollup/rollup-linux-arm64-musl@4.21.0': resolution: {integrity: sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==} cpu: [arm64] os: [linux] + '@rollup/rollup-linux-arm64-musl@4.36.0': + resolution: {integrity: sha512-QiGnhScND+mAAtfHqeT+cB1S9yFnNQ/EwCg5yE3MzoaZZnIV0RV9O5alJAoJKX/sBONVKeZdMfO8QSaWEygMhw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.36.0': + resolution: {integrity: sha512-1ZPyEDWF8phd4FQtTzMh8FQwqzvIjLsl6/84gzUxnMNFBtExBtpL51H67mV9xipuxl1AEAerRBgBwFNpkw8+Lg==} + cpu: [loong64] + os: [linux] + '@rollup/rollup-linux-powerpc64le-gnu@4.21.0': resolution: {integrity: sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==} cpu: [ppc64] os: [linux] + '@rollup/rollup-linux-powerpc64le-gnu@4.36.0': + resolution: {integrity: sha512-VMPMEIUpPFKpPI9GZMhJrtu8rxnp6mJR3ZzQPykq4xc2GmdHj3Q4cA+7avMyegXy4n1v+Qynr9fR88BmyO74tg==} + cpu: [ppc64] + os: [linux] + '@rollup/rollup-linux-riscv64-gnu@4.21.0': resolution: {integrity: sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==} cpu: [riscv64] os: [linux] + '@rollup/rollup-linux-riscv64-gnu@4.36.0': + resolution: {integrity: sha512-ttE6ayb/kHwNRJGYLpuAvB7SMtOeQnVXEIpMtAvx3kepFQeowVED0n1K9nAdraHUPJ5hydEMxBpIR7o4nrm8uA==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.21.0': resolution: {integrity: sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==} cpu: [s390x] os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.36.0': + resolution: {integrity: sha512-4a5gf2jpS0AIe7uBjxDeUMNcFmaRTbNv7NxI5xOCs4lhzsVyGR/0qBXduPnoWf6dGC365saTiwag8hP1imTgag==} + cpu: [s390x] + os: [linux] + '@rollup/rollup-linux-x64-gnu@4.21.0': resolution: {integrity: sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==} cpu: [x64] os: [linux] + '@rollup/rollup-linux-x64-gnu@4.36.0': + resolution: {integrity: sha512-5KtoW8UWmwFKQ96aQL3LlRXX16IMwyzMq/jSSVIIyAANiE1doaQsx/KRyhAvpHlPjPiSU/AYX/8m+lQ9VToxFQ==} + cpu: [x64] + os: [linux] + '@rollup/rollup-linux-x64-musl@4.21.0': resolution: {integrity: sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==} cpu: [x64] os: [linux] + '@rollup/rollup-linux-x64-musl@4.36.0': + resolution: {integrity: sha512-sycrYZPrv2ag4OCvaN5js+f01eoZ2U+RmT5as8vhxiFz+kxwlHrsxOwKPSA8WyS+Wc6Epid9QeI/IkQ9NkgYyQ==} + cpu: [x64] + os: [linux] + '@rollup/rollup-win32-arm64-msvc@4.21.0': resolution: {integrity: sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==} cpu: [arm64] os: [win32] + '@rollup/rollup-win32-arm64-msvc@4.36.0': + resolution: {integrity: sha512-qbqt4N7tokFwwSVlWDsjfoHgviS3n/vZ8LK0h1uLG9TYIRuUTJC88E1xb3LM2iqZ/WTqNQjYrtmtGmrmmawB6A==} + cpu: [arm64] + os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.21.0': resolution: {integrity: sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==} cpu: [ia32] os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.36.0': + resolution: {integrity: sha512-t+RY0JuRamIocMuQcfwYSOkmdX9dtkr1PbhKW42AMvaDQa+jOdpUYysroTF/nuPpAaQMWp7ye+ndlmmthieJrQ==} + cpu: [ia32] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.21.0': resolution: {integrity: sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-msvc@4.36.0': + resolution: {integrity: sha512-aRXd7tRZkWLqGbChgcMMDEHjOKudo1kChb1Jt1IfR8cY/KIpgNviLeJy5FUb9IpSuQj8dU2fAYNMPW/hLKOSTw==} + cpu: [x64] + os: [win32] + '@rushstack/eslint-patch@1.10.4': resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} '@scure/base@1.1.7': resolution: {integrity: sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==} + '@scure/base@1.2.1': + resolution: {integrity: sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ==} + + '@scure/base@1.2.4': + resolution: {integrity: sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==} + '@scure/bip32@1.4.0': resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + '@scure/bip32@1.6.2': + resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + '@scure/bip39@1.3.0': resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + '@scure/starknet@0.3.0': resolution: {integrity: sha512-Ma66yZlwa5z00qI5alSxdWtIpky5LBhy22acVFdoC5kwwbd9uDyMWEYzWHdNyKmQg9t5Y2UOXzINMeb3yez+Gw==} '@scure/starknet@1.0.0': resolution: {integrity: sha512-o5J57zY0f+2IL/mq8+AYJJ4Xpc1fOtDhr+mFQKbHnYFmm3WQrC+8zj2HEgxak1a+x86mhmBC1Kq305KUpVf0wg==} + '@scure/starknet@1.1.0': + resolution: {integrity: sha512-83g3M6Ix2qRsPN4wqLDqiRZ2GBNbjVWfboJE/9UjfG+MHr6oDSu/CWgy8hsBSJejr09DkkL+l0Ze4KVrlCIdtQ==} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -1129,38 +1555,84 @@ packages: '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - '@starknet-io/types-js@0.7.7': - resolution: {integrity: sha512-WLrpK7LIaIb8Ymxu6KF/6JkGW1sso988DweWu7p5QY/3y7waBIiPvzh27D9bX5KIJNRDyOoOVoHVEKYUYWZ/RQ==} + '@starknet-io/types-js@0.7.10': + resolution: {integrity: sha512-1VtCqX4AHWJlRRSYGSn+4X1mqolI1Tdq62IwzoU2vUuEE72S1OlEeGhpvd6XsdqXcfHmVzYfj8k1XtKBQqwo9w==} - '@starknet-react/chains@0.1.7': - resolution: {integrity: sha512-UNh97I1SvuJKaAhKOmpEk8JcWuZWMlPG/ba2HcvFYL9x/47BKndJ+Da9V+iJFtkHUjreVnajT1snsaz1XMG+UQ==} + '@starknet-react/chains@3.1.2': + resolution: {integrity: sha512-/Oldb4AVYdvHXzlBRxu01s0WwdOjqL2Q47BAmiv07/aBRU7mSZl6r/6l+bYKNrChSZl7WVnlpb+ojfwhRpbGcw==} - '@starknet-react/core@2.9.0': - resolution: {integrity: sha512-UdRo454/g2lb0YsNAUJohJ2w21LlahcEXQlkWrddoKFubRY6Q0b39hec0eZOCqfU0Z1Sh7kF1XYvI5t9xL4yTQ==} + '@starknet-react/core@3.7.2': + resolution: {integrity: sha512-5l6IlXqYzbnInVPwL2VdSwmIiaNnTjm4iYnEGSSVUUPyklHr3bdXaZoILJWcIQ0NaF2ebhNhoKYL8GDHiSKTPw==} peerDependencies: - get-starknet-core: ^3.2.0 + get-starknet-core: ^4.0.0 react: ^18.0 - starknet: ^5.25.0 + starknet: ^6.11.0 - '@tanstack/query-core@5.52.0': - resolution: {integrity: sha512-U1DOEgltjUwalN6uWYTewSnA14b+tE7lSylOiASKCAO61ENJeCq9VVD/TXHA6O5u9+6v5+UgGYBSccTKDoyMqw==} + '@tanstack/query-core@5.68.0': + resolution: {integrity: sha512-r8rFYYo8/sY/LNaOqX84h12w7EQev4abFXDWy4UoDVUJzJ5d9Fbmb8ayTi7ScG+V0ap44SF3vNs/45mkzDGyGw==} - '@tanstack/react-query@5.52.1': - resolution: {integrity: sha512-soyn4dNIUZ8US8NaPVXv06gkZFHaZnPfKWPDjRJjFRW3Y7WZ0jx72eT6zhw3VQlkMPysmXye8l35ewPHspKgbQ==} + '@tanstack/react-query@5.68.0': + resolution: {integrity: sha512-mMOdGDKlwTP/WV72QqSNf4PAMeoBp/DqBHQ222wBfb51Looi8QUqnCnb9O98ZgvNISmy6fzxRGBJdZ+9IBvX2Q==} peerDependencies: react: ^18 || ^19 - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@testing-library/jest-dom@6.6.3': + resolution: {integrity: sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react-hooks@8.0.1': + resolution: {integrity: sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==} + engines: {node: '>=12'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 + react: ^16.9.0 || ^17.0.0 + react-dom: ^16.9.0 || ^17.0.0 + react-test-renderer: ^16.9.0 || ^17.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-dom: + optional: true + react-test-renderer: + optional: true + + '@testing-library/react@16.2.0': + resolution: {integrity: sha512-2cSskAvA1QNtKc8Y9VJQRv0tm3hLVgxRGDB+KYhIaPQJ1I+RHbhIXcM+zClKXzMes/wshsMVzf4B9vS4IZpqDQ==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1174,12 +1646,15 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} - '@types/bun@1.1.7': - resolution: {integrity: sha512-iIIn26SOX8qI5E8Juh+0rUgBmFHvll1akscwerhp9O/fHZGdQBWNLJkkRg/3z2Mh6a3ZgWUIkXViLZZYg47TXw==} + '@types/bun@1.1.11': + resolution: {integrity: sha512-0N7D/H/8sbf9JMkaG5F3+I/cB4TlhKTkO9EskEWP8XDr8aVcDe4EywSnU4cnyZy6tar1dq70NeFNkqMEUigthw==} '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -1192,8 +1667,8 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/jest@29.5.12': - resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} + '@types/jsdom@20.0.1': + resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -1210,14 +1685,20 @@ packages: '@types/node@20.16.1': resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} + '@types/node@22.13.10': + resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} + + '@types/node@22.5.5': + resolution: {integrity: sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==} + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - '@types/prop-types@15.7.12': - resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + '@types/prop-types@15.7.14': + resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} - '@types/react@18.3.4': - resolution: {integrity: sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==} + '@types/react@18.3.18': + resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} '@types/semver@7.5.8': resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} @@ -1225,6 +1706,9 @@ packages: '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/triple-beam@1.3.5': resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} @@ -1343,10 +1827,68 @@ packages: typescript: optional: true + '@vitest/expect@2.0.5': + resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + + '@vitest/expect@2.1.9': + resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + + '@vitest/mocker@2.1.9': + resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.0.5': + resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/runner@2.0.5': + resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==} + + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + + '@vitest/snapshot@2.0.5': + resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/spy@2.0.5': + resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + + '@vitest/spy@2.1.9': + resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + + '@vitest/utils@2.0.5': + resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + + abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead + abi-wan-kanabi@2.2.3: resolution: {integrity: sha512-JlqiAl9CPvTm5kKG0QXmVCWNWoC/XyRMOeT77cQlbxXWllgjf6SqUmaNqFon72C2o5OSZids+5FvLdsw6dvWaw==} hasBin: true + abi-wan-kanabi@2.2.4: + resolution: {integrity: sha512-0aA81FScmJCPX+8UvkXLki3X1+yPQuWxEkqXBVKltgPAK79J+NB+Lp5DouMXa7L6f+zcRlIA/6XO7BN/q9fnvg==} + hasBin: true + abitype@1.0.5: resolution: {integrity: sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==} peerDependencies: @@ -1358,6 +1900,20 @@ packages: zod: optional: true + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + acorn-globals@7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1372,6 +1928,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -1429,6 +1989,13 @@ packages: aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -1465,12 +2032,23 @@ packages: resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -1536,9 +2114,10 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} + browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -1553,9 +2132,11 @@ packages: bun-types@1.1.25: resolution: {integrity: sha512-WpRb8/N3S5IE8UYdIn39+0Is1XzxsC78+MCe5cIdaer0lfFs6+DREtQH9TM6KJNKTxBYDvbx81RwbvxS5+CkVQ==} + bun-types@1.1.30: + resolution: {integrity: sha512-mGh7NLisOXskBU62DxLS+/nwmLlCYHYAkCzdo4DZ9+fzrpP41hAdOqaN4DO6tQfenHb4pYb0/shw29k4/6I2yQ==} + bun@1.1.25: resolution: {integrity: sha512-N+KvGq6jcA88QgFVoOMSr2s4sZ9u+R7Tn6Hci25mdygZxa3jgaS91PMNxpEJKkyTBLOhH5E8erx+tqtRLyFbJA==} - cpu: [arm64, x64] os: [darwin, linux, win32] hasBin: true @@ -1588,14 +2169,29 @@ packages: caniuse-lite@1.0.30001651: resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} + caniuse-lite@1.0.30001705: + resolution: {integrity: sha512-S0uyMMiYvA7CxNgomYBwwwPUnWzFD83f3B1ce5jHUfHTH//QL6hHsreI8RVC5606R4ssqravelYO5TU6t8sEyg==} + cardinal@2.1.1: resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} hasBin: true + chai@5.1.1: + resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + engines: {node: '>=12'} + + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} + chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -1607,6 +2203,10 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -1615,8 +2215,8 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cjs-module-lexer@1.3.1: - resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} clean-regexp@1.0.0: resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} @@ -1662,9 +2262,13 @@ packages: colorspace@1.1.4: resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} @@ -1695,6 +2299,19 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + + cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + + cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -1705,6 +2322,10 @@ packages: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} + data-urls@3.0.2: + resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} + engines: {node: '>=12'} + data-view-buffer@1.0.1: resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} engines: {node: '>= 0.4'} @@ -1734,10 +2355,22 @@ packages: supports-color: optional: true + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize@4.0.0: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} + decimal.js@10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + dedent@1.5.3: resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: @@ -1746,6 +2379,10 @@ packages: babel-plugin-macros: optional: true + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-equal@2.2.3: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} @@ -1765,6 +2402,14 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -1805,6 +2450,17 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + domexception@4.0.0: + resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} + engines: {node: '>=12'} + deprecated: Use your platform's native DOMException instead + dotenv-cli@7.4.2: resolution: {integrity: sha512-SbUj8l61zIbzyhIbg0FwPJq6+wjbzdn9oEtozQpZ6kW2ihCcapKVZj49oCT3oPM+mgQm+itgvUQcG5szxVrZTA==} hasBin: true @@ -1821,13 +2477,15 @@ packages: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} - hasBin: true + electron-to-chromium@1.5.120: + resolution: {integrity: sha512-oTUp3gfX1gZI+xfD2djr2rzQdHCwHzPQrrK0CD7WpTdF0nPdQ/INcRVjWgLdCT4a9W3jFObR9DAfsuyFQnI8CQ==} electron-to-chromium@1.5.13: resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==} @@ -1853,6 +2511,10 @@ packages: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -1875,6 +2537,9 @@ packages: resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} engines: {node: '>= 0.4'} + es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + es-object-atoms@1.0.0: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} engines: {node: '>= 0.4'} @@ -1895,6 +2560,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.23.1: resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} engines: {node: '>=18'} @@ -1904,6 +2574,10 @@ packages: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -1916,14 +2590,19 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + eslint-config-prettier@9.1.0: resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' - eslint-config-turbo@1.13.4: - resolution: {integrity: sha512-+we4eWdZlmlEn7LnhXHCIPX/wtujbHCS7XjQM/TN09BHNEl2fZ8id4rHfdfUKIYTSKyy8U/nNyJ0DNoZj5Q8bw==} + eslint-config-turbo@2.1.2: + resolution: {integrity: sha512-UCNwxBrTOx0K41h1OrwMg7vPdGvcGSAlj40ZzpuUi0S2Muac2UOs+6F2dMYQiKg7lX2HAtyHXlF0T2wlWNHjGg==} peerDependencies: eslint: '>6.6.0' @@ -2039,8 +2718,8 @@ packages: eslint-plugin-tsdoc@0.2.17: resolution: {integrity: sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==} - eslint-plugin-turbo@1.13.4: - resolution: {integrity: sha512-82GfMzrewI/DJB92Bbch239GWbGx4j1zvjk1lqb06lxIlMPnVwUHVwPbAnLfyLG3JuhLv9whxGkO/q1CL18JTg==} + eslint-plugin-turbo@2.1.2: + resolution: {integrity: sha512-q2ikGubfVLZDPEKliiuubZc3sI5oqbKIZJ6fRi6Bldv8E3cMNH3Qt7g6hXZV4+GxwQbzEEteCYSBNbOn1DBqRg==} peerDependencies: eslint: '>6.6.0' @@ -2116,6 +2795,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -2127,10 +2809,18 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} + expect-type@1.2.0: + resolution: {integrity: sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==} + engines: {node: '>=12.0.0'} + expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2175,9 +2865,6 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -2190,8 +2877,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - find-yarn-workspace-root2@1.2.16: - resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + find-yarn-workspace-root@2.0.0: + resolution: {integrity: sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==} flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} @@ -2214,6 +2901,10 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -2230,6 +2921,10 @@ packages: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2256,6 +2951,9 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -2264,8 +2962,8 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} - get-starknet-core@3.3.3: - resolution: {integrity: sha512-IscL4lAigJpc/9Idkg07sdyUOXkB+/goTDQm8EhMGn/nIAW4rn04d+D47ils75drNQIfZZKDIIZrWrbIKvjoWA==} + get-starknet-core@3.3.5: + resolution: {integrity: sha512-EiXfbVp1ZIKc4jjGA5hEyNsy9rnkH4ALpiMCD+4G2jtqo/Gq4TrcVzh//mJclLA8yHRh3576H1vbAeH5zA1CiQ==} peerDependencies: starknet: ^5.18.0 @@ -2280,6 +2978,10 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + get-symbol-description@1.0.2: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} @@ -2377,9 +3079,21 @@ packages: hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + html-encoding-sniffer@3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} + html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} @@ -2387,10 +3101,18 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + ignore-by-default@1.0.1: resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} @@ -2398,9 +3120,6 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - immutable@4.3.7: - resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} - import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -2470,6 +3189,10 @@ packages: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + is-data-view@1.0.1: resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} engines: {node: '>= 0.4'} @@ -2478,6 +3201,11 @@ packages: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2529,6 +3257,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -2545,6 +3276,10 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -2580,6 +3315,10 @@ packages: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -2594,6 +3333,11 @@ packages: peerDependencies: ws: '*' + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -2624,11 +3368,6 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jake@10.9.2: - resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} - engines: {node: '>=10'} - hasBin: true - jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2671,6 +3410,15 @@ packages: resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-environment-jsdom@29.7.0: + resolution: {integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + jest-environment-node@29.7.0: resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2776,6 +3524,15 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsdom@20.0.3: + resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} + engines: {node: '>=14'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true @@ -2790,6 +3547,11 @@ packages: engines: {node: '>=6'} hasBin: true + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -2802,6 +3564,10 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json-stable-stringify@1.1.1: + resolution: {integrity: sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==} + engines: {node: '>= 0.4'} + json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -2817,6 +3583,9 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonify@0.0.1: + resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -2824,6 +3593,9 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + klaw-sync@6.0.0: + resolution: {integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==} + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -2857,10 +3629,6 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - load-yaml-file@0.2.0: - resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} - engines: {node: '>=6'} - loading-cli@1.1.2: resolution: {integrity: sha512-M1ntfXHpdGoQxfaqKBOQPwSrTr9EIoTgj664Q9UVSbSnJvAFdribo+Ij//1jvACgrGHaTvfKoD9PG3NOxGj44g==} @@ -2872,9 +3640,6 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -2902,6 +3667,12 @@ packages: lossless-json@4.0.1: resolution: {integrity: sha512-l0L+ppmgPDnb+JGxNLndPtJZGNf6+ZmVaQzoxQm3u6TXmhdnsA+YtdVR8DjzZd/em58686CQhOFDPewfJ4l7MA==} + loupe@3.1.1: + resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} + + loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -2911,6 +3682,16 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} @@ -2932,10 +3713,22 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -2980,6 +3773,16 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.10: + resolution: {integrity: sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -3006,11 +3809,19 @@ packages: node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + nodemon@3.1.4: resolution: {integrity: sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==} engines: {node: '>=10'} hasBin: true + nodemon@3.1.9: + resolution: {integrity: sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==} + engines: {node: '>=10'} + hasBin: true + normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -3022,6 +3833,13 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nwsapi@2.2.12: + resolution: {integrity: sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -3068,6 +3886,14 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + open@7.4.2: + resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} + engines: {node: '>=8'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -3079,6 +3905,14 @@ packages: outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + ox@0.6.9: + resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -3110,6 +3944,9 @@ packages: package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + package-manager-detector@0.2.2: + resolution: {integrity: sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==} + pako@2.1.0: resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} @@ -3121,6 +3958,14 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + patch-package@8.0.0: + resolution: {integrity: sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==} + engines: {node: '>=14', npm: '>5'} + hasBin: true + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -3133,6 +3978,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -3144,9 +3993,22 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -3189,9 +4051,16 @@ packages: yaml: optional: true - preferred-pm@3.1.4: - resolution: {integrity: sha512-lEHd+yEm22jXdCphDrkvIJQU66EuLojPPtvZkpKIkiD+l0DMThF/niqZKJSoU8Vl7iuvtmzyMhir9LdVy5WMnA==} - engines: {node: '>=10'} + postcss@8.4.45: + resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + postinstall-postinstall@2.1.0: + resolution: {integrity: sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -3220,6 +4089,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3264,12 +4137,31 @@ packages: peerDependencies: react: ^18.3.1 + react-error-boundary@3.1.4: + resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} + engines: {node: '>=10', npm: '>=6'} + peerDependencies: + react: '>=16.13.1' + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-shallow-renderer@16.15.0: + resolution: {integrity: sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + + react-test-renderer@18.3.1: + resolution: {integrity: sha512-KkAgygexHUkQqtvvx/otwxtuFu5cVjfzTCtjXLH9boS19/Nbtg84zS7wIQn39G8IlrhThBpQsMKkq5ZHZIYFXA==} + peerDependencies: + react: ^18.3.1 + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -3294,6 +4186,10 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + redeyed@2.1.1: resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} @@ -3338,13 +4234,18 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} engines: {node: '>=10'} resolve@1.19.0: resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -3357,6 +4258,11 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -3367,6 +4273,11 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rollup@4.36.0: + resolution: {integrity: sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -3388,6 +4299,10 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -3404,6 +4319,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} @@ -3438,6 +4358,9 @@ packages: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -3455,6 +4378,10 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + slash@2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -3470,6 +4397,10 @@ packages: resolution: {integrity: sha512-d76wfhgUuGypKqY72Unm5LFnMpACbdxXsLPcL27pOsSrmVqH3PztFp1uq+Z22suk15h7vXmTesuh2aEjdCqb5w==} hasBin: true + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} @@ -3506,9 +4437,21 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + starknet@6.11.0: resolution: {integrity: sha512-u50KrGDi9fbu1Ogu7ynwF/tSeFlp3mzOg1/Y5x50tYFICImo3OfY4lOz9OtYDk404HK4eUujKkhov9tG7GAKlg==} + starknet@6.23.1: + resolution: {integrity: sha512-vQV9luXpmwZZs9RVZaRwm2iD8T0PYx1AzgZeQsCvD89tR0HwUF0paty27ZzuJrdPe0CmAs/ipAYFCE55jbj0RQ==} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + std-env@3.8.1: + resolution: {integrity: sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==} + stop-iteration-iterator@1.0.0: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} @@ -3569,6 +4512,10 @@ packages: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -3598,6 +4545,9 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + synckit@0.9.1: resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==} engines: {node: ^14.18.0 || >=16.0.0} @@ -3627,6 +4577,28 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinypool@1.0.1: + resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -3656,6 +4628,10 @@ packages: tr46@1.0.1: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -3673,30 +4649,6 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - ts-jest@29.2.5: - resolution: {integrity: sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==} - engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 - esbuild: '*' - jest: ^29.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/transform': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - ts-mixer@6.0.4: resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} @@ -3753,38 +4705,38 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - turbo-darwin-64@1.13.4: - resolution: {integrity: sha512-A0eKd73R7CGnRinTiS7txkMElg+R5rKFp9HV7baDiEL4xTG1FIg/56Vm7A5RVgg8UNgG2qNnrfatJtb+dRmNdw==} + turbo-darwin-64@2.1.3: + resolution: {integrity: sha512-ouJOm0g0YyoBuhmikEujVCBGo3Zr0lbSOWFIsQtWUTItC88F2w2byhjtsYGPXQwMlTbXwmoBU2lOCfWNkeEwHQ==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@1.13.4: - resolution: {integrity: sha512-eG769Q0NF6/Vyjsr3mKCnkG/eW6dKMBZk6dxWOdrHfrg6QgfkBUk0WUUujzdtVPiUIvsh4l46vQrNVd9EOtbyA==} + turbo-darwin-arm64@2.1.3: + resolution: {integrity: sha512-j2FOJsK4LAOtHQlb3Oom0yWB/Vi0nF1ljInr311mVzHoFAJRZtfW2fRvdZRb/lBUwjSp8be58qWHzANIcrA0OA==} cpu: [arm64] os: [darwin] - turbo-linux-64@1.13.4: - resolution: {integrity: sha512-Bq0JphDeNw3XEi+Xb/e4xoKhs1DHN7OoLVUbTIQz+gazYjigVZvtwCvgrZI7eW9Xo1eOXM2zw2u1DGLLUfmGkQ==} + turbo-linux-64@2.1.3: + resolution: {integrity: sha512-ubRHkI1gSel7H7wsmxKK8C9UlLWqg/2dkCC88LFupaK6TKgvBKqDqA0Z1M9C/escK0Jsle2k0H8bybV9OYIl4Q==} cpu: [x64] os: [linux] - turbo-linux-arm64@1.13.4: - resolution: {integrity: sha512-BJcXw1DDiHO/okYbaNdcWN6szjXyHWx9d460v6fCHY65G8CyqGU3y2uUTPK89o8lq/b2C8NK0yZD+Vp0f9VoIg==} + turbo-linux-arm64@2.1.3: + resolution: {integrity: sha512-LffUL+e5wv7BtD6DgnM2kKOlDkMo2eRjhbAjVnrCD3wi2ug0tl6NDzajnHHjtaMyOnIf4AvzSKdLWsBxafGBQA==} cpu: [arm64] os: [linux] - turbo-windows-64@1.13.4: - resolution: {integrity: sha512-OFFhXHOFLN7A78vD/dlVuuSSVEB3s9ZBj18Tm1hk3aW1HTWTuAw0ReN6ZNlVObZUHvGy8d57OAGGxf2bT3etQw==} + turbo-windows-64@2.1.3: + resolution: {integrity: sha512-S9SvcZZoaq5jKr6kA6eF7/xgQhVn8Vh7PVy5lono9zybvhyL4eY++y2PaLToIgL8G9IcbLmgOC73ExNjFBg9XQ==} cpu: [x64] os: [win32] - turbo-windows-arm64@1.13.4: - resolution: {integrity: sha512-u5A+VOKHswJJmJ8o8rcilBfU5U3Y1TTAfP9wX8bFh8teYF1ghP0EhtMRLjhtp6RPa+XCxHHVA2CiC3gbh5eg5g==} + turbo-windows-arm64@2.1.3: + resolution: {integrity: sha512-twlEo8lRrGbrR6T/ZklUIquW3IlFCEtywklgVA81aIrSBm56+GEVpSrHhIlsx1hiYeSNrs+GpDwZGe+V7fvEVQ==} cpu: [arm64] os: [win32] - turbo@1.13.4: - resolution: {integrity: sha512-1q7+9UJABuBAHrcC4Sxp5lOqYS5mvxRrwa33wpIyM18hlOCpRD/fTJNxZ0vhbMcJmz15o9kkVm743mPn7p6jpQ==} + turbo@2.1.3: + resolution: {integrity: sha512-lY0yj2GH2a2a3NExZ3rGe+rHUVeFE2aXuRAue57n+08E7Z7N7YCmynju0kPC1grAQzERmoLpKrmzmWd+PNiADw==} hasBin: true type-check@0.4.0: @@ -3832,6 +4784,11 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} @@ -3844,6 +4801,9 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -3862,6 +4822,12 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -3892,6 +4858,140 @@ packages: typescript: optional: true + viem@2.23.11: + resolution: {integrity: sha512-yPkHJt4Vn88kLlrv8mrtVN54PW4vNLWRWDScf8SaHK2f44VlMk5IZbMJw4ycUoW9K9GUvCMrYuUa34MAcwYHIg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + vite-node@2.0.5: + resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite-node@2.1.9: + resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.14: + resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vite@5.4.3: + resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.0.5: + resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.0.5 + '@vitest/ui': 2.0.5 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vitest@2.1.9: + resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.9 + '@vitest/ui': 2.1.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@4.0.0: + resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} + engines: {node: '>=14'} + walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -3908,9 +5008,25 @@ packages: webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -3928,10 +5044,6 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-pm@2.2.0: - resolution: {integrity: sha512-MOiaDbA5ZZgUjkeMWM5EkJp4loW5ZRoa5bc3/aeMox/PJelMhE6t7S/mLuiY43DBupyxH+S0U1bTui9kWUlmsw==} - engines: {node: '>=8.15'} - which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} @@ -3945,6 +5057,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + winston-transport@4.7.1: resolution: {integrity: sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA==} engines: {node: '>= 12.0.0'} @@ -3987,6 +5104,25 @@ packages: utf-8-validate: optional: true + ws@8.18.1: + resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -3997,6 +5133,11 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml@2.5.1: + resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} + engines: {node: '>= 14'} + hasBin: true + yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} @@ -4028,10 +5169,17 @@ packages: zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + zod@3.24.2: + resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} + snapshots: + '@adobe/css-tools@4.4.2': {} + '@adraffy/ens-normalize@1.10.0': {} + '@adraffy/ens-normalize@1.11.0': {} + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 @@ -4042,8 +5190,18 @@ snapshots: '@babel/highlight': 7.24.7 picocolors: 1.0.1 + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + optional: true + '@babel/compat-data@7.25.4': {} + '@babel/compat-data@7.26.8': + optional: true + '@babel/core@7.25.2': dependencies: '@ampproject/remapping': 2.3.0 @@ -4064,6 +5222,27 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/core@7.26.10': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.10 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) + '@babel/helpers': 7.26.10 + '@babel/parser': 7.26.10 + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.10 + '@babel/types': 7.26.10 + convert-source-map: 2.0.0 + debug: 4.4.0(supports-color@5.5.0) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + optional: true + '@babel/eslint-parser@7.25.1(@babel/core@7.25.2)(eslint@8.57.0)': dependencies: '@babel/core': 7.25.2 @@ -4079,6 +5258,15 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 + '@babel/generator@7.26.10': + dependencies: + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + optional: true + '@babel/helper-compilation-targets@7.25.2': dependencies: '@babel/compat-data': 7.25.4 @@ -4087,6 +5275,15 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-compilation-targets@7.26.5': + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + optional: true + '@babel/helper-module-imports@7.24.7': dependencies: '@babel/traverse': 7.25.4 @@ -4094,6 +5291,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@7.25.9': + dependencies: + '@babel/traverse': 7.26.10 + '@babel/types': 7.26.10 + transitivePeerDependencies: + - supports-color + optional: true + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -4104,7 +5309,18 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-plugin-utils@7.24.8': {} + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.26.10 + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/helper-plugin-utils@7.26.5': + optional: true '@babel/helper-simple-access@7.24.7': dependencies: @@ -4115,15 +5331,30 @@ snapshots: '@babel/helper-string-parser@7.24.8': {} + '@babel/helper-string-parser@7.25.9': + optional: true + '@babel/helper-validator-identifier@7.24.7': {} + '@babel/helper-validator-identifier@7.25.9': + optional: true + '@babel/helper-validator-option@7.24.8': {} + '@babel/helper-validator-option@7.25.9': + optional: true + '@babel/helpers@7.25.0': dependencies: '@babel/template': 7.25.0 '@babel/types': 7.25.4 + '@babel/helpers@7.26.10': + dependencies: + '@babel/template': 7.26.9 + '@babel/types': 7.26.10 + optional: true + '@babel/highlight@7.24.7': dependencies: '@babel/helper-validator-identifier': 7.24.7 @@ -4135,101 +5366,134 @@ snapshots: dependencies: '@babel/types': 7.25.4 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': + '@babel/parser@7.26.10': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/types': 7.26.10 + optional: true - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true - '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true + + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + optional: true '@babel/runtime@7.25.4': dependencies: regenerator-runtime: 0.14.1 + '@babel/runtime@7.26.10': + dependencies: + regenerator-runtime: 0.14.1 + '@babel/template@7.25.0': dependencies: '@babel/code-frame': 7.24.7 '@babel/parser': 7.25.4 '@babel/types': 7.25.4 + '@babel/template@7.26.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 + optional: true + '@babel/traverse@7.25.4': dependencies: '@babel/code-frame': 7.24.7 @@ -4242,21 +5506,40 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.26.10': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.10 + '@babel/parser': 7.26.10 + '@babel/template': 7.26.9 + '@babel/types': 7.26.10 + debug: 4.4.0(supports-color@5.5.0) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + optional: true + '@babel/types@7.25.4': dependencies: '@babel/helper-string-parser': 7.24.8 '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 - '@bcoe/v8-coverage@0.2.3': {} + '@babel/types@7.26.10': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + optional: true + + '@bcoe/v8-coverage@0.2.3': + optional: true - '@changesets/apply-release-plan@7.0.4': + '@changesets/apply-release-plan@7.0.5': dependencies: - '@babel/runtime': 7.25.4 - '@changesets/config': 3.0.2 + '@changesets/config': 3.0.3 '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.0 - '@changesets/should-skip-package': 0.1.0 + '@changesets/git': 3.0.1 + '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 @@ -4267,12 +5550,11 @@ snapshots: resolve-from: 5.0.0 semver: 7.6.3 - '@changesets/assemble-release-plan@6.0.3': + '@changesets/assemble-release-plan@6.0.4': dependencies: - '@babel/runtime': 7.25.4 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.1 - '@changesets/should-skip-package': 0.1.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 semver: 7.6.3 @@ -4281,46 +5563,42 @@ snapshots: dependencies: '@changesets/types': 6.0.0 - '@changesets/cli@2.27.7': + '@changesets/cli@2.27.9': dependencies: - '@babel/runtime': 7.25.4 - '@changesets/apply-release-plan': 7.0.4 - '@changesets/assemble-release-plan': 6.0.3 + '@changesets/apply-release-plan': 7.0.5 + '@changesets/assemble-release-plan': 6.0.4 '@changesets/changelog-git': 0.2.0 - '@changesets/config': 3.0.2 + '@changesets/config': 3.0.3 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.1 - '@changesets/get-release-plan': 4.0.3 - '@changesets/git': 3.0.0 - '@changesets/logger': 0.1.0 - '@changesets/pre': 2.0.0 - '@changesets/read': 0.6.0 - '@changesets/should-skip-package': 0.1.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-release-plan': 4.0.4 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 - '@changesets/write': 0.3.1 + '@changesets/write': 0.3.2 '@manypkg/get-packages': 1.1.3 - '@types/semver': 7.5.8 ansi-colors: 4.1.3 - chalk: 2.4.2 ci-info: 3.9.0 enquirer: 2.4.1 external-editor: 3.1.0 fs-extra: 7.0.1 - human-id: 1.0.2 mri: 1.2.0 - outdent: 0.5.0 p-limit: 2.3.0 - preferred-pm: 3.1.4 + package-manager-detector: 0.2.2 + picocolors: 1.1.0 resolve-from: 5.0.0 semver: 7.6.3 spawndamnit: 2.0.0 term-size: 2.2.1 - '@changesets/config@3.0.2': + '@changesets/config@3.0.3': dependencies: '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.1 - '@changesets/logger': 0.1.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/logger': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 @@ -4330,67 +5608,60 @@ snapshots: dependencies: extendable-error: 0.1.7 - '@changesets/get-dependents-graph@2.1.1': + '@changesets/get-dependents-graph@2.1.2': dependencies: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - chalk: 2.4.2 - fs-extra: 7.0.1 + picocolors: 1.1.0 semver: 7.6.3 - '@changesets/get-release-plan@4.0.3': + '@changesets/get-release-plan@4.0.4': dependencies: - '@babel/runtime': 7.25.4 - '@changesets/assemble-release-plan': 6.0.3 - '@changesets/config': 3.0.2 - '@changesets/pre': 2.0.0 - '@changesets/read': 0.6.0 + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/config': 3.0.3 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 '@changesets/get-version-range-type@0.4.0': {} - '@changesets/git@3.0.0': + '@changesets/git@3.0.1': dependencies: - '@babel/runtime': 7.25.4 '@changesets/errors': 0.2.0 - '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 micromatch: 4.0.8 spawndamnit: 2.0.0 - '@changesets/logger@0.1.0': + '@changesets/logger@0.1.1': dependencies: - chalk: 2.4.2 + picocolors: 1.1.0 '@changesets/parse@0.4.0': dependencies: '@changesets/types': 6.0.0 js-yaml: 3.14.1 - '@changesets/pre@2.0.0': + '@changesets/pre@2.0.1': dependencies: - '@babel/runtime': 7.25.4 '@changesets/errors': 0.2.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.0': + '@changesets/read@0.6.1': dependencies: - '@babel/runtime': 7.25.4 - '@changesets/git': 3.0.0 - '@changesets/logger': 0.1.0 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 '@changesets/parse': 0.4.0 '@changesets/types': 6.0.0 - chalk: 2.4.2 fs-extra: 7.0.1 p-filter: 2.1.0 + picocolors: 1.1.0 - '@changesets/should-skip-package@0.1.0': + '@changesets/should-skip-package@0.1.1': dependencies: - '@babel/runtime': 7.25.4 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 @@ -4398,9 +5669,8 @@ snapshots: '@changesets/types@6.0.0': {} - '@changesets/write@0.3.1': + '@changesets/write@0.3.2': dependencies: - '@babel/runtime': 7.25.4 '@changesets/types': 6.0.0 fs-extra: 7.0.1 human-id: 1.0.2 @@ -4421,108 +5691,162 @@ snapshots: '@esbuild/aix-ppc64@0.20.2': optional: true + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.23.1': optional: true '@esbuild/android-arm64@0.20.2': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.23.1': optional: true '@esbuild/android-arm@0.20.2': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.23.1': optional: true '@esbuild/android-x64@0.20.2': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.23.1': optional: true '@esbuild/darwin-arm64@0.20.2': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.23.1': optional: true '@esbuild/darwin-x64@0.20.2': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.23.1': optional: true '@esbuild/freebsd-arm64@0.20.2': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.23.1': optional: true '@esbuild/freebsd-x64@0.20.2': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.23.1': optional: true '@esbuild/linux-arm64@0.20.2': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.23.1': optional: true '@esbuild/linux-arm@0.20.2': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.23.1': optional: true '@esbuild/linux-ia32@0.20.2': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.23.1': optional: true '@esbuild/linux-loong64@0.20.2': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.23.1': optional: true '@esbuild/linux-mips64el@0.20.2': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.23.1': optional: true '@esbuild/linux-ppc64@0.20.2': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.23.1': optional: true '@esbuild/linux-riscv64@0.20.2': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.23.1': optional: true '@esbuild/linux-s390x@0.20.2': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.23.1': optional: true '@esbuild/linux-x64@0.20.2': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.23.1': optional: true '@esbuild/netbsd-x64@0.20.2': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.23.1': optional: true @@ -4532,30 +5856,45 @@ snapshots: '@esbuild/openbsd-x64@0.20.2': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.23.1': optional: true '@esbuild/sunos-x64@0.20.2': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.23.1': optional: true '@esbuild/win32-arm64@0.20.2': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.23.1': optional: true '@esbuild/win32-ia32@0.20.2': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.23.1': optional: true '@esbuild/win32-x64@0.20.2': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.23.1': optional: true @@ -4622,33 +5961,36 @@ snapshots: get-package-type: 0.1.0 js-yaml: 3.14.1 resolve-from: 5.0.0 + optional: true - '@istanbuljs/schema@0.1.3': {} + '@istanbuljs/schema@0.1.3': + optional: true '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 20.16.1 + '@types/node': 22.13.10 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 + optional: true - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4))': + '@jest/core@29.7.0': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.1 + '@types/node': 22.13.10 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) + jest-config: 29.7.0(@types/node@22.13.10) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -4668,6 +6010,7 @@ snapshots: - babel-plugin-macros - supports-color - ts-node + optional: true '@jest/environment@29.7.0': dependencies: @@ -4679,6 +6022,7 @@ snapshots: '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 + optional: true '@jest/expect@29.7.0': dependencies: @@ -4686,6 +6030,7 @@ snapshots: jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color + optional: true '@jest/fake-timers@29.7.0': dependencies: @@ -4704,6 +6049,7 @@ snapshots: jest-mock: 29.7.0 transitivePeerDependencies: - supports-color + optional: true '@jest/reporters@29.7.0': dependencies: @@ -4713,7 +6059,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.16.1 + '@types/node': 22.13.10 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -4733,6 +6079,7 @@ snapshots: v8-to-istanbul: 9.3.0 transitivePeerDependencies: - supports-color + optional: true '@jest/schemas@29.6.3': dependencies: @@ -4743,6 +6090,7 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 + optional: true '@jest/test-result@29.7.0': dependencies: @@ -4750,6 +6098,7 @@ snapshots: '@jest/types': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 collect-v8-coverage: 1.0.2 + optional: true '@jest/test-sequencer@29.7.0': dependencies: @@ -4757,10 +6106,11 @@ snapshots: graceful-fs: 4.2.11 jest-haste-map: 29.7.0 slash: 3.0.0 + optional: true '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.10 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 @@ -4777,6 +6127,7 @@ snapshots: write-file-atomic: 4.0.2 transitivePeerDependencies: - supports-color + optional: true '@jest/types@29.6.3': dependencies: @@ -4793,6 +6144,13 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + optional: true + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/set-array@1.2.1': {} @@ -4860,12 +6218,24 @@ snapshots: dependencies: '@noble/hashes': 1.4.0 + '@noble/curves@1.7.0': + dependencies: + '@noble/hashes': 1.6.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + '@noble/hashes@1.3.2': {} '@noble/hashes@1.3.3': {} '@noble/hashes@1.4.0': {} + '@noble/hashes@1.6.0': {} + + '@noble/hashes@1.7.1': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4910,66 +6280,138 @@ snapshots: '@rollup/rollup-android-arm-eabi@4.21.0': optional: true + '@rollup/rollup-android-arm-eabi@4.36.0': + optional: true + '@rollup/rollup-android-arm64@4.21.0': optional: true + '@rollup/rollup-android-arm64@4.36.0': + optional: true + '@rollup/rollup-darwin-arm64@4.21.0': optional: true + '@rollup/rollup-darwin-arm64@4.36.0': + optional: true + '@rollup/rollup-darwin-x64@4.21.0': optional: true + '@rollup/rollup-darwin-x64@4.36.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.36.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.36.0': + optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.21.0': optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.36.0': + optional: true + '@rollup/rollup-linux-arm-musleabihf@4.21.0': optional: true + '@rollup/rollup-linux-arm-musleabihf@4.36.0': + optional: true + '@rollup/rollup-linux-arm64-gnu@4.21.0': optional: true + '@rollup/rollup-linux-arm64-gnu@4.36.0': + optional: true + '@rollup/rollup-linux-arm64-musl@4.21.0': optional: true + '@rollup/rollup-linux-arm64-musl@4.36.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.36.0': + optional: true + '@rollup/rollup-linux-powerpc64le-gnu@4.21.0': optional: true + '@rollup/rollup-linux-powerpc64le-gnu@4.36.0': + optional: true + '@rollup/rollup-linux-riscv64-gnu@4.21.0': optional: true + '@rollup/rollup-linux-riscv64-gnu@4.36.0': + optional: true + '@rollup/rollup-linux-s390x-gnu@4.21.0': optional: true + '@rollup/rollup-linux-s390x-gnu@4.36.0': + optional: true + '@rollup/rollup-linux-x64-gnu@4.21.0': optional: true + '@rollup/rollup-linux-x64-gnu@4.36.0': + optional: true + '@rollup/rollup-linux-x64-musl@4.21.0': optional: true + '@rollup/rollup-linux-x64-musl@4.36.0': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.21.0': optional: true + '@rollup/rollup-win32-arm64-msvc@4.36.0': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.21.0': optional: true + '@rollup/rollup-win32-ia32-msvc@4.36.0': + optional: true + '@rollup/rollup-win32-x64-msvc@4.21.0': optional: true + '@rollup/rollup-win32-x64-msvc@4.36.0': + optional: true + '@rushstack/eslint-patch@1.10.4': {} '@scure/base@1.1.7': {} + '@scure/base@1.2.1': {} + + '@scure/base@1.2.4': {} + '@scure/bip32@1.4.0': dependencies: '@noble/curves': 1.4.0 '@noble/hashes': 1.4.0 '@scure/base': 1.1.7 + '@scure/bip32@1.6.2': + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.4 + '@scure/bip39@1.3.0': dependencies: '@noble/hashes': 1.4.0 '@scure/base': 1.1.7 + '@scure/bip39@1.5.4': + dependencies: + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.4 + '@scure/starknet@0.3.0': dependencies: '@noble/curves': 1.2.0 @@ -4980,6 +6422,11 @@ snapshots: '@noble/curves': 1.3.0 '@noble/hashes': 1.3.3 + '@scure/starknet@1.1.0': + dependencies: + '@noble/curves': 1.7.0 + '@noble/hashes': 1.6.0 + '@sinclair/typebox@0.27.8': {} '@sinonjs/commons@3.0.1': @@ -4990,27 +6437,92 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@starknet-io/types-js@0.7.7': {} + '@starknet-io/types-js@0.7.10': {} + + '@starknet-react/chains@3.1.2': {} - '@starknet-react/chains@0.1.7': {} + '@starknet-react/core@3.7.2(get-starknet-core@3.3.5(starknet@6.23.1))(react@18.3.1)(starknet@6.23.1)(typescript@5.8.2)': + dependencies: + '@starknet-io/types-js': 0.7.10 + '@starknet-react/chains': 3.1.2 + '@tanstack/react-query': 5.68.0(react@18.3.1) + abi-wan-kanabi: 2.2.4 + eventemitter3: 5.0.1 + get-starknet-core: 3.3.5(starknet@6.23.1) + react: 18.3.1 + starknet: 6.23.1 + viem: 2.23.11(typescript@5.8.2)(zod@3.24.2) + zod: 3.24.2 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate - '@starknet-react/core@2.9.0(get-starknet-core@3.3.3(starknet@6.11.0))(react@18.3.1)(starknet@6.11.0)': + '@starknet-react/core@3.7.2(get-starknet-core@4.0.0)(react@18.3.1)(starknet@6.23.1)(typescript@5.8.2)': dependencies: - '@starknet-react/chains': 0.1.7 - '@tanstack/react-query': 5.52.1(react@18.3.1) + '@starknet-io/types-js': 0.7.10 + '@starknet-react/chains': 3.1.2 + '@tanstack/react-query': 5.68.0(react@18.3.1) + abi-wan-kanabi: 2.2.4 eventemitter3: 5.0.1 - get-starknet-core: 3.3.3(starknet@6.11.0) - immutable: 4.3.7 + get-starknet-core: 4.0.0 + react: 18.3.1 + starknet: 6.23.1 + viem: 2.23.11(typescript@5.8.2)(zod@3.24.2) + zod: 3.24.2 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@tanstack/query-core@5.68.0': {} + + '@tanstack/react-query@5.68.0(react@18.3.1)': + dependencies: + '@tanstack/query-core': 5.68.0 react: 18.3.1 - starknet: 6.11.0 - zod: 3.23.8 - '@tanstack/query-core@5.52.0': {} + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/runtime': 7.25.4 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 - '@tanstack/react-query@5.52.1(react@18.3.1)': + '@testing-library/jest-dom@6.6.3': dependencies: - '@tanstack/query-core': 5.52.0 + '@adobe/css-tools': 4.4.2 + aria-query: 5.3.2 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + + '@testing-library/react-hooks@8.0.1(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react-test-renderer@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.4 react: 18.3.1 + react-error-boundary: 3.1.4(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.18 + react-dom: 18.3.1(react@18.3.1) + react-test-renderer: 18.3.1(react@18.3.1) + + '@testing-library/react@16.2.0(@testing-library/dom@10.4.0)(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.10 + '@testing-library/dom': 10.4.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.18 + + '@tootallnate/once@2.0.0': {} '@tsconfig/node10@1.0.11': {} @@ -5020,36 +6532,45 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@types/aria-query@5.0.4': {} + '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.25.4 - '@babel/types': 7.25.4 + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 + optional: true '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.25.4 + '@babel/types': 7.26.10 + optional: true '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.25.4 - '@babel/types': 7.25.4 + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 + optional: true '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.25.4 + '@babel/types': 7.26.10 + optional: true - '@types/bun@1.1.7': + '@types/bun@1.1.11': dependencies: - bun-types: 1.1.25 + bun-types: 1.1.30 '@types/estree@1.0.5': {} + '@types/estree@1.0.6': {} + '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 20.16.1 + '@types/node': 22.13.10 + optional: true '@types/istanbul-lib-coverage@2.0.6': {} @@ -5061,10 +6582,11 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 - '@types/jest@29.5.12': + '@types/jsdom@20.0.1': dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 + '@types/node': 20.16.1 + '@types/tough-cookie': 4.0.5 + parse5: 7.1.2 '@types/json-schema@7.0.15': {} @@ -5080,24 +6602,34 @@ snapshots: dependencies: undici-types: 6.19.8 + '@types/node@22.13.10': + dependencies: + undici-types: 6.20.0 + + '@types/node@22.5.5': + dependencies: + undici-types: 6.19.8 + '@types/normalize-package-data@2.4.4': {} - '@types/prop-types@15.7.12': {} + '@types/prop-types@15.7.14': {} - '@types/react@18.3.4': + '@types/react@18.3.18': dependencies: - '@types/prop-types': 15.7.12 + '@types/prop-types': 15.7.14 csstype: 3.1.3 '@types/semver@7.5.8': {} '@types/stack-utils@2.0.3': {} + '@types/tough-cookie@4.0.5': {} + '@types/triple-beam@1.3.5': {} '@types/ws@8.5.12': dependencies: - '@types/node': 20.12.14 + '@types/node': 20.16.1 '@types/yargs-parser@21.0.3': {} @@ -5168,7 +6700,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.6(supports-color@5.5.0) + debug: 4.4.0(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 @@ -5265,6 +6797,83 @@ snapshots: - jest - supports-color + '@vitest/expect@2.0.5': + dependencies: + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.1.1 + tinyrainbow: 1.2.0 + + '@vitest/expect@2.1.9': + dependencies: + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.2.0 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.9(vite@5.4.14(@types/node@22.13.10))': + dependencies: + '@vitest/spy': 2.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 5.4.14(@types/node@22.13.10) + + '@vitest/pretty-format@2.0.5': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.0.5': + dependencies: + '@vitest/utils': 2.0.5 + pathe: 1.1.2 + + '@vitest/runner@2.1.9': + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + + '@vitest/snapshot@2.0.5': + dependencies: + '@vitest/pretty-format': 2.0.5 + magic-string: 0.30.11 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.17 + pathe: 1.1.2 + + '@vitest/spy@2.0.5': + dependencies: + tinyspy: 3.0.2 + + '@vitest/spy@2.1.9': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.0.5': + dependencies: + '@vitest/pretty-format': 2.0.5 + estree-walker: 3.0.3 + loupe: 3.1.1 + tinyrainbow: 1.2.0 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + + '@yarnpkg/lockfile@1.1.0': {} + + abab@2.0.6: {} + abi-wan-kanabi@2.2.3: dependencies: ansicolors: 0.3.2 @@ -5272,10 +6881,27 @@ snapshots: fs-extra: 10.1.0 yargs: 17.7.2 - abitype@1.0.5(typescript@5.5.4)(zod@3.23.8): + abi-wan-kanabi@2.2.4: + dependencies: + ansicolors: 0.3.2 + cardinal: 2.1.1 + fs-extra: 10.1.0 + yargs: 17.7.2 + + abitype@1.0.5(typescript@5.5.4)(zod@3.24.2): optionalDependencies: typescript: 5.5.4 - zod: 3.23.8 + zod: 3.24.2 + + abitype@1.0.8(typescript@5.8.2)(zod@3.24.2): + optionalDependencies: + typescript: 5.8.2 + zod: 3.24.2 + + acorn-globals@7.0.1: + dependencies: + acorn: 8.12.1 + acorn-walk: 8.3.3 acorn-jsx@5.3.2(acorn@8.12.1): dependencies: @@ -5287,6 +6913,12 @@ snapshots: acorn@8.12.1: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.0(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -5299,6 +6931,7 @@ snapshots: ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 + optional: true ansi-regex@5.0.1: {} @@ -5337,6 +6970,12 @@ snapshots: dependencies: deep-equal: 2.2.3 + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 @@ -5404,10 +7043,16 @@ snapshots: is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 + assertion-error@2.0.1: {} + ast-types-flow@0.0.8: {} async@3.2.6: {} + asynckit@0.4.0: {} + + at-least-node@1.0.0: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 @@ -5418,60 +7063,65 @@ snapshots: dependencies: deep-equal: 2.2.3 - babel-jest@29.7.0(@babel/core@7.25.2): + babel-jest@29.7.0(@babel/core@7.26.10): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.10 '@jest/transform': 29.7.0 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.25.2) + babel-preset-jest: 29.6.3(@babel/core@7.26.10) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 transitivePeerDependencies: - supports-color + optional: true babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-plugin-utils': 7.26.5 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 test-exclude: 6.0.0 transitivePeerDependencies: - supports-color + optional: true babel-plugin-jest-hoist@29.6.3: dependencies: - '@babel/template': 7.25.0 - '@babel/types': 7.25.4 + '@babel/template': 7.26.9 + '@babel/types': 7.26.10 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.6 + optional: true - babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.2): - dependencies: - '@babel/core': 7.25.2 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) - - babel-preset-jest@29.6.3(@babel/core@7.25.2): + babel-preset-current-node-syntax@1.1.0(@babel/core@7.26.10): + dependencies: + '@babel/core': 7.26.10 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.26.10) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.10) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.10) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.26.10) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.10) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.10) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.26.10) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.26.10) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.10) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.26.10) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.10) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.26.10) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.10) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.10) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.10) + optional: true + + babel-preset-jest@29.6.3(@babel/core@7.26.10): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.10 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.10) + optional: true balanced-match@1.0.2: {} @@ -5503,15 +7153,21 @@ snapshots: node-releases: 2.0.18 update-browserslist-db: 1.1.0(browserslist@4.23.3) - bs-logger@0.2.6: + browserslist@4.24.4: dependencies: - fast-json-stable-stringify: 2.1.0 + caniuse-lite: 1.0.30001705 + electron-to-chromium: 1.5.120 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.4) + optional: true bser@2.1.1: dependencies: node-int64: 0.4.0 + optional: true - buffer-from@1.1.2: {} + buffer-from@1.1.2: + optional: true builtin-modules@3.3.0: {} @@ -5520,6 +7176,11 @@ snapshots: '@types/node': 20.12.14 '@types/ws': 8.5.12 + bun-types@1.1.30: + dependencies: + '@types/node': 20.12.14 + '@types/ws': 8.5.12 + bun@1.1.25: optionalDependencies: '@oven/bun-darwin-aarch64': 1.1.25 @@ -5548,32 +7209,60 @@ snapshots: callsites@3.1.0: {} - camelcase@5.3.1: {} + camelcase@5.3.1: + optional: true camelcase@6.3.0: {} caniuse-lite@1.0.30001651: {} + caniuse-lite@1.0.30001705: + optional: true + cardinal@2.1.1: dependencies: ansicolors: 0.3.2 redeyed: 2.1.1 + chai@5.1.1: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.1 + pathval: 2.0.0 + + chai@5.2.0: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 + chalk@3.0.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - char-regex@1.0.2: {} + char-regex@1.0.2: + optional: true chardet@0.7.0: {} + check-error@2.1.1: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -5588,7 +7277,8 @@ snapshots: ci-info@3.9.0: {} - cjs-module-lexer@1.3.1: {} + cjs-module-lexer@1.4.3: + optional: true clean-regexp@1.0.0: dependencies: @@ -5606,9 +7296,11 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - co@4.6.0: {} + co@4.6.0: + optional: true - collect-v8-coverage@1.0.2: {} + collect-v8-coverage@1.0.2: + optional: true color-convert@1.9.3: dependencies: @@ -5639,7 +7331,11 @@ snapshots: color: 3.2.1 text-hex: 1.0.0 - commander@11.1.0: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@12.1.0: {} commander@4.1.1: {} @@ -5649,13 +7345,13 @@ snapshots: convert-source-map@2.0.0: {} - create-jest@29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)): + create-jest@29.7.0: dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) + jest-config: 29.7.0(@types/node@22.13.10) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -5663,6 +7359,7 @@ snapshots: - babel-plugin-macros - supports-color - ts-node + optional: true create-require@1.1.1: {} @@ -5678,12 +7375,28 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css.escape@1.5.1: {} + + cssom@0.3.8: {} + + cssom@0.5.0: {} + + cssstyle@2.3.0: + dependencies: + cssom: 0.3.8 + csstype@3.1.3: {} damerau-levenshtein@1.0.8: {} data-uri-to-buffer@4.0.1: {} + data-urls@3.0.2: + dependencies: + abab: 2.0.6 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + data-view-buffer@1.0.1: dependencies: call-bind: 1.0.7 @@ -5718,9 +7431,20 @@ snapshots: optionalDependencies: supports-color: 8.1.1 + debug@4.4.0(supports-color@5.5.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 + decamelize@4.0.0: {} - dedent@1.5.3: {} + decimal.js@10.4.3: {} + + dedent@1.5.3: + optional: true + + deep-eql@5.0.2: {} deep-equal@2.2.3: dependencies: @@ -5745,7 +7469,8 @@ snapshots: deep-is@0.1.4: {} - deepmerge@4.3.1: {} + deepmerge@4.3.1: + optional: true define-data-property@1.1.4: dependencies: @@ -5759,15 +7484,21 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + delayed-stream@1.0.0: {} + + dequal@2.0.3: {} + detect-indent@6.1.0: {} detect-indent@7.0.1: {} - detect-newline@3.1.0: {} + detect-newline@3.1.0: + optional: true detect-newline@4.0.1: {} - diff-sequences@29.6.3: {} + diff-sequences@29.6.3: + optional: true diff@4.0.2: {} @@ -5785,10 +7516,18 @@ snapshots: dependencies: esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + + domexception@4.0.0: + dependencies: + webidl-conversions: 7.0.0 + dotenv-cli@7.4.2: dependencies: cross-spawn: 7.0.3 - dotenv: 16.4.5 + dotenv: 16.4.7 dotenv-expand: 10.0.0 minimist: 1.2.8 @@ -5798,15 +7537,17 @@ snapshots: dotenv@16.4.5: {} + dotenv@16.4.7: {} + eastasianwidth@0.2.0: {} - ejs@3.1.10: - dependencies: - jake: 10.9.2 + electron-to-chromium@1.5.120: + optional: true electron-to-chromium@1.5.13: {} - emittery@0.13.1: {} + emittery@0.13.1: + optional: true emoji-regex@8.0.0: {} @@ -5824,6 +7565,8 @@ snapshots: ansi-colors: 4.1.3 strip-ansi: 6.0.1 + entities@4.5.0: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -5912,6 +7655,8 @@ snapshots: iterator.prototype: 1.1.2 safe-array-concat: 1.1.2 + es-module-lexer@1.6.0: {} + es-object-atoms@1.0.0: dependencies: es-errors: 1.3.0 @@ -5958,6 +7703,32 @@ snapshots: '@esbuild/win32-ia32': 0.20.2 '@esbuild/win32-x64': 0.20.2 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.23.1: optionalDependencies: '@esbuild/aix-ppc64': 0.23.1 @@ -5987,20 +7758,31 @@ snapshots: escalade@3.1.2: {} + escalade@3.2.0: + optional: true + escape-string-regexp@1.0.5: {} escape-string-regexp@2.0.0: {} escape-string-regexp@4.0.0: {} + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + eslint-config-prettier@9.1.0(eslint@8.57.0): dependencies: eslint: 8.57.0 - eslint-config-turbo@1.13.4(eslint@8.57.0): + eslint-config-turbo@2.1.2(eslint@8.57.0): dependencies: eslint: 8.57.0 - eslint-plugin-turbo: 1.13.4(eslint@8.57.0) + eslint-plugin-turbo: 2.1.2(eslint@8.57.0) eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)): dependencies: @@ -6081,7 +7863,7 @@ snapshots: eslint: 8.57.0 optionalDependencies: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) - jest: 29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) + jest: 29.7.0 transitivePeerDependencies: - supports-color - typescript @@ -6160,7 +7942,7 @@ snapshots: '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - eslint-plugin-turbo@1.13.4(eslint@8.57.0): + eslint-plugin-turbo@2.1.2(eslint@8.57.0): dependencies: dotenv: 16.0.3 eslint: 8.57.0 @@ -6275,6 +8057,10 @@ snapshots: estraverse@5.3.0: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + esutils@2.0.3: {} eventemitter3@5.0.1: {} @@ -6291,7 +8077,22 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - exit@0.1.2: {} + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + exit@0.1.2: + optional: true + + expect-type@1.2.0: {} expect@29.7.0: dependencies: @@ -6300,6 +8101,7 @@ snapshots: jest-matcher-utils: 29.7.0 jest-message-util: 29.7.0 jest-util: 29.7.0 + optional: true extendable-error@0.1.7: {} @@ -6330,6 +8132,7 @@ snapshots: fb-watchman@2.0.2: dependencies: bser: 2.1.1 + optional: true fecha@4.2.3: {} @@ -6347,10 +8150,6 @@ snapshots: dependencies: flat-cache: 3.2.0 - filelist@1.0.4: - dependencies: - minimatch: 5.1.6 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -6365,10 +8164,9 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - find-yarn-workspace-root2@1.2.16: + find-yarn-workspace-root@2.0.0: dependencies: micromatch: 4.0.8 - pkg-dir: 4.2.0 flat-cache@3.2.0: dependencies: @@ -6391,6 +8189,12 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 @@ -6413,6 +8217,13 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -6433,6 +8244,8 @@ snapshots: get-caller-file@2.0.5: {} + get-func-name@2.0.2: {} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -6441,21 +8254,24 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.2 - get-package-type@0.1.0: {} + get-package-type@0.1.0: + optional: true - get-starknet-core@3.3.3(starknet@6.11.0): + get-starknet-core@3.3.5(starknet@6.23.1): dependencies: '@module-federation/runtime': 0.1.21 - starknet: 6.11.0 + starknet: 6.23.1 get-starknet-core@4.0.0: dependencies: - '@starknet-io/types-js': 0.7.7 + '@starknet-io/types-js': 0.7.10 get-stdin@9.0.0: {} get-stream@6.0.1: {} + get-stream@8.0.1: {} + get-symbol-description@1.0.2: dependencies: call-bind: 1.0.7 @@ -6564,22 +8380,46 @@ snapshots: hosted-git-info@2.8.9: {} - html-escaper@2.0.2: {} + html-encoding-sniffer@3.0.0: + dependencies: + whatwg-encoding: 2.0.0 + + html-escaper@2.0.2: + optional: true + + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.4.0(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.0(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color human-id@1.0.2: {} human-signals@2.1.0: {} + human-signals@5.0.0: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + ignore-by-default@1.0.1: {} ignore@5.3.2: {} - immutable@4.3.7: {} - import-fresh@3.3.0: dependencies: parent-module: 1.0.1 @@ -6589,6 +8429,7 @@ snapshots: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 + optional: true imurmurhash@0.1.4: {} @@ -6648,6 +8489,11 @@ snapshots: dependencies: hasown: 2.0.2 + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + optional: true + is-data-view@1.0.1: dependencies: is-typed-array: 1.1.13 @@ -6656,6 +8502,8 @@ snapshots: dependencies: has-tostringtag: 1.0.2 + is-docker@2.2.1: {} + is-extglob@2.1.1: {} is-finalizationregistry@1.0.2: @@ -6664,7 +8512,8 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-generator-fn@2.1.0: {} + is-generator-fn@2.1.0: + optional: true is-generator-function@1.0.10: dependencies: @@ -6690,6 +8539,8 @@ snapshots: is-plain-obj@4.1.0: {} + is-potential-custom-element-name@1.0.1: {} + is-regex@1.1.4: dependencies: call-bind: 1.0.7 @@ -6703,6 +8554,8 @@ snapshots: is-stream@2.0.1: {} + is-stream@3.0.0: {} + is-string@1.0.7: dependencies: has-tostringtag: 1.0.2 @@ -6734,6 +8587,10 @@ snapshots: is-windows@1.0.2: {} + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + isarray@2.0.5: {} isexe@2.0.0: {} @@ -6749,46 +8606,56 @@ snapshots: dependencies: ws: 8.17.1 - istanbul-lib-coverage@3.2.2: {} + isows@1.0.6(ws@8.18.1): + dependencies: + ws: 8.18.1 + + istanbul-lib-coverage@3.2.2: + optional: true istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.25.2 - '@babel/parser': 7.25.4 + '@babel/core': 7.26.10 + '@babel/parser': 7.26.10 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: - supports-color + optional: true istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.25.2 - '@babel/parser': 7.25.4 + '@babel/core': 7.26.10 + '@babel/parser': 7.26.10 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.6.3 + semver: 7.7.1 transitivePeerDependencies: - supports-color + optional: true istanbul-lib-report@3.0.1: dependencies: istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 + optional: true istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.6(supports-color@5.5.0) + debug: 4.4.0(supports-color@5.5.0) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color + optional: true istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + optional: true iterator.prototype@1.1.2: dependencies: @@ -6804,18 +8671,12 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jake@10.9.2: - dependencies: - async: 3.2.6 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 - jest-changed-files@29.7.0: dependencies: execa: 5.1.1 jest-util: 29.7.0 p-limit: 3.1.0 + optional: true jest-circus@29.7.0: dependencies: @@ -6823,7 +8684,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.1 + '@types/node': 22.13.10 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -6842,17 +8703,18 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros - supports-color + optional: true - jest-cli@29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)): + jest-cli@29.7.0: dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) + '@jest/core': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) + create-jest: 29.7.0 exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) + jest-config: 29.7.0(@types/node@22.13.10) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -6861,13 +8723,14 @@ snapshots: - babel-plugin-macros - supports-color - ts-node + optional: true - jest-config@29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)): + jest-config@29.7.0(@types/node@22.13.10): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.10 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.25.2) + babel-jest: 29.7.0(@babel/core@7.26.10) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -6887,11 +8750,11 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 20.16.1 - ts-node: 10.9.2(@types/node@20.16.1)(typescript@5.5.4) + '@types/node': 22.13.10 transitivePeerDependencies: - babel-plugin-macros - supports-color + optional: true jest-diff@29.7.0: dependencies: @@ -6899,10 +8762,12 @@ snapshots: diff-sequences: 29.6.3 jest-get-type: 29.6.3 pretty-format: 29.7.0 + optional: true jest-docblock@29.7.0: dependencies: detect-newline: 3.1.0 + optional: true jest-each@29.7.0: dependencies: @@ -6911,23 +8776,41 @@ snapshots: jest-get-type: 29.6.3 jest-util: 29.7.0 pretty-format: 29.7.0 + optional: true - jest-environment-node@29.7.0: + jest-environment-jsdom@29.7.0: dependencies: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 + '@types/jsdom': 20.0.1 '@types/node': 20.16.1 jest-mock: 29.7.0 jest-util: 29.7.0 + jsdom: 20.0.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.13.10 + jest-mock: 29.7.0 + jest-util: 29.7.0 + optional: true - jest-get-type@29.6.3: {} + jest-get-type@29.6.3: + optional: true jest-haste-map@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.16.1 + '@types/node': 22.13.10 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -6938,11 +8821,13 @@ snapshots: walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 + optional: true jest-leak-detector@29.7.0: dependencies: jest-get-type: 29.6.3 pretty-format: 29.7.0 + optional: true jest-matcher-utils@29.7.0: dependencies: @@ -6950,6 +8835,7 @@ snapshots: jest-diff: 29.7.0 jest-get-type: 29.6.3 pretty-format: 29.7.0 + optional: true jest-message-util@29.7.0: dependencies: @@ -6972,8 +8858,10 @@ snapshots: jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): optionalDependencies: jest-resolve: 29.7.0 + optional: true - jest-regex-util@29.6.3: {} + jest-regex-util@29.6.3: + optional: true jest-resolve-dependencies@29.7.0: dependencies: @@ -6981,6 +8869,7 @@ snapshots: jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color + optional: true jest-resolve@29.7.0: dependencies: @@ -6990,9 +8879,10 @@ snapshots: jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) jest-util: 29.7.0 jest-validate: 29.7.0 - resolve: 1.22.8 - resolve.exports: 2.0.2 + resolve: 1.22.10 + resolve.exports: 2.0.3 slash: 3.0.0 + optional: true jest-runner@29.7.0: dependencies: @@ -7001,7 +8891,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.1 + '@types/node': 22.13.10 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -7019,6 +8909,7 @@ snapshots: source-map-support: 0.5.13 transitivePeerDependencies: - supports-color + optional: true jest-runtime@29.7.0: dependencies: @@ -7029,9 +8920,9 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.1 + '@types/node': 22.13.10 chalk: 4.1.2 - cjs-module-lexer: 1.3.1 + cjs-module-lexer: 1.4.3 collect-v8-coverage: 1.0.2 glob: 7.2.3 graceful-fs: 4.2.11 @@ -7046,18 +8937,19 @@ snapshots: strip-bom: 4.0.0 transitivePeerDependencies: - supports-color + optional: true jest-snapshot@29.7.0: dependencies: - '@babel/core': 7.25.2 - '@babel/generator': 7.25.5 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.25.2) - '@babel/types': 7.25.4 + '@babel/core': 7.26.10 + '@babel/generator': 7.26.10 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10) + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.10) + '@babel/types': 7.26.10 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.10) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -7068,9 +8960,10 @@ snapshots: jest-util: 29.7.0 natural-compare: 1.4.0 pretty-format: 29.7.0 - semver: 7.6.3 + semver: 7.7.1 transitivePeerDependencies: - supports-color + optional: true jest-util@29.7.0: dependencies: @@ -7089,36 +8982,40 @@ snapshots: jest-get-type: 29.6.3 leven: 3.1.0 pretty-format: 29.7.0 + optional: true jest-watcher@29.7.0: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.1 + '@types/node': 22.13.10 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 jest-util: 29.7.0 string-length: 4.0.2 + optional: true jest-worker@29.7.0: dependencies: - '@types/node': 20.16.1 + '@types/node': 22.13.10 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 + optional: true - jest@29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)): + jest@29.7.0: dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) + '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) + jest-cli: 29.7.0 transitivePeerDependencies: - '@types/node' - babel-plugin-macros - supports-color - ts-node + optional: true jju@1.4.0: {} @@ -7135,12 +9032,48 @@ snapshots: dependencies: argparse: 2.0.1 + jsdom@20.0.3: + dependencies: + abab: 2.0.6 + acorn: 8.12.1 + acorn-globals: 7.0.1 + cssom: 0.5.0 + cssstyle: 2.3.0 + data-urls: 3.0.2 + decimal.js: 10.4.3 + domexception: 4.0.0 + escodegen: 2.1.0 + form-data: 4.0.0 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.12 + parse5: 7.1.2 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 4.1.4 + w3c-xmlserializer: 4.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + ws: 8.17.1 + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + jsesc@0.5.0: {} jsesc@2.5.2: {} jsesc@3.0.2: {} + jsesc@3.1.0: + optional: true + json-buffer@3.0.1: {} json-parse-even-better-errors@2.3.1: {} @@ -7149,6 +9082,13 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json-stable-stringify@1.1.1: + dependencies: + call-bind: 1.0.7 + isarray: 2.0.5 + jsonify: 0.0.1 + object-keys: 1.1.1 + json5@1.0.2: dependencies: minimist: 1.2.8 @@ -7165,6 +9105,8 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonify@0.0.1: {} + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -7176,7 +9118,12 @@ snapshots: dependencies: json-buffer: 3.0.1 - kleur@3.0.3: {} + klaw-sync@6.0.0: + dependencies: + graceful-fs: 4.2.11 + + kleur@3.0.3: + optional: true kuler@2.0.0: {} @@ -7186,7 +9133,8 @@ snapshots: dependencies: language-subtag-registry: 0.3.23 - leven@3.1.0: {} + leven@3.1.0: + optional: true levn@0.4.1: dependencies: @@ -7199,13 +9147,6 @@ snapshots: load-tsconfig@0.2.5: {} - load-yaml-file@0.2.0: - dependencies: - graceful-fs: 4.2.11 - js-yaml: 3.14.1 - pify: 4.0.1 - strip-bom: 3.0.0 - loading-cli@1.1.2: dependencies: colors-cli: 1.0.33 @@ -7218,8 +9159,6 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash.memoize@4.1.2: {} - lodash.merge@4.6.2: {} lodash.sortby@4.7.0: {} @@ -7248,6 +9187,12 @@ snapshots: lossless-json@4.0.1: {} + loupe@3.1.1: + dependencies: + get-func-name: 2.0.2 + + loupe@3.1.3: {} + lru-cache@10.4.3: {} lru-cache@4.1.5: @@ -7259,15 +9204,27 @@ snapshots: dependencies: yallist: 3.1.1 + lz-string@1.5.0: {} + + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + make-dir@4.0.0: dependencies: - semver: 7.6.3 + semver: 7.7.1 + optional: true make-error@1.3.6: {} makeerror@1.0.12: dependencies: tmpl: 1.0.5 + optional: true merge-stream@2.0.0: {} @@ -7278,8 +9235,16 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mimic-fn@2.1.0: {} + mimic-fn@4.0.0: {} + min-indent@1.0.1: {} minimatch@3.1.2: @@ -7337,6 +9302,10 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + nanoid@3.3.10: {} + + nanoid@3.3.7: {} + natural-compare@1.4.0: {} node-domexception@1.0.0: {} @@ -7351,10 +9320,14 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 - node-int64@0.4.0: {} + node-int64@0.4.0: + optional: true node-releases@2.0.18: {} + node-releases@2.0.19: + optional: true + nodemon@3.1.4: dependencies: chokidar: 3.6.0 @@ -7368,6 +9341,19 @@ snapshots: touch: 3.1.1 undefsafe: 2.0.5 + nodemon@3.1.9: + dependencies: + chokidar: 3.6.0 + debug: 4.4.0(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.7.1 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.1 + undefsafe: 2.0.5 + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 @@ -7381,6 +9367,12 @@ snapshots: dependencies: path-key: 3.1.1 + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + nwsapi@2.2.12: {} + object-assign@4.1.1: {} object-inspect@1.13.2: {} @@ -7436,6 +9428,15 @@ snapshots: dependencies: mimic-fn: 2.1.0 + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + open@7.4.2: + dependencies: + is-docker: 2.2.1 + is-wsl: 2.2.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -7449,6 +9450,20 @@ snapshots: outdent@0.5.0: {} + ox@0.6.9(typescript@5.8.2)(zod@3.24.2): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.2)(zod@3.24.2) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - zod + p-filter@2.1.0: dependencies: p-map: 2.1.0 @@ -7475,6 +9490,8 @@ snapshots: package-json-from-dist@1.0.0: {} + package-manager-detector@0.2.2: {} + pako@2.1.0: {} parent-module@1.0.1: @@ -7488,12 +9505,36 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse5@7.1.2: + dependencies: + entities: 4.5.0 + + patch-package@8.0.0: + dependencies: + '@yarnpkg/lockfile': 1.1.0 + chalk: 4.1.2 + ci-info: 3.9.0 + cross-spawn: 7.0.3 + find-yarn-workspace-root: 2.0.0 + fs-extra: 9.1.0 + json-stable-stringify: 1.1.1 + klaw-sync: 6.0.0 + minimist: 1.2.8 + open: 7.4.2 + rimraf: 2.7.1 + semver: 7.6.3 + slash: 2.0.0 + tmp: 0.0.33 + yaml: 2.5.1 + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-scurry@1.11.1: @@ -7503,8 +9544,16 @@ snapshots: path-type@4.0.0: {} + pathe@1.1.2: {} + + pathval@2.0.0: {} + picocolors@1.0.1: {} + picocolors@1.1.0: {} + + picocolors@1.1.1: {} + picomatch@2.3.1: {} pify@4.0.1: {} @@ -7514,23 +9563,33 @@ snapshots: pkg-dir@4.2.0: dependencies: find-up: 4.1.0 + optional: true pluralize@8.0.0: {} possible-typed-array-names@1.0.0: {} - postcss-load-config@6.0.1(tsx@4.17.0): + postcss-load-config@6.0.1(postcss@8.5.3)(tsx@4.17.0)(yaml@2.5.1): dependencies: lilconfig: 3.1.2 optionalDependencies: + postcss: 8.5.3 tsx: 4.17.0 + yaml: 2.5.1 - preferred-pm@3.1.4: + postcss@8.4.45: dependencies: - find-up: 5.0.0 - find-yarn-workspace-root2: 1.2.16 - path-exists: 4.0.0 - which-pm: 2.2.0 + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.1 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.10 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postinstall-postinstall@2.1.0: {} prelude-ls@1.2.1: {} @@ -7550,6 +9609,12 @@ snapshots: prettier@3.3.3: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 @@ -7560,6 +9625,7 @@ snapshots: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 + optional: true prop-types@15.8.1: dependencies: @@ -7575,7 +9641,8 @@ snapshots: punycode@2.3.1: {} - pure-rand@6.1.0: {} + pure-rand@6.1.0: + optional: true querystringify@2.2.0: {} @@ -7593,10 +9660,30 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 + react-error-boundary@3.1.4(react@18.3.1): + dependencies: + '@babel/runtime': 7.25.4 + react: 18.3.1 + react-is@16.13.1: {} + react-is@17.0.2: {} + react-is@18.3.1: {} + react-shallow-renderer@16.15.0(react@18.3.1): + dependencies: + object-assign: 4.1.1 + react: 18.3.1 + react-is: 18.3.1 + + react-test-renderer@18.3.1(react@18.3.1): + dependencies: + react: 18.3.1 + react-is: 18.3.1 + react-shallow-renderer: 16.15.0(react@18.3.1) + scheduler: 0.23.2 + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -7631,6 +9718,11 @@ snapshots: dependencies: picomatch: 2.3.1 + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + redeyed@2.1.1: dependencies: esprima: 4.0.1 @@ -7667,6 +9759,7 @@ snapshots: resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 + optional: true resolve-from@4.0.0: {} @@ -7674,13 +9767,21 @@ snapshots: resolve-pkg-maps@1.0.0: {} - resolve.exports@2.0.2: {} + resolve.exports@2.0.3: + optional: true resolve@1.19.0: dependencies: is-core-module: 2.15.1 path-parse: 1.0.7 + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + optional: true + resolve@1.22.8: dependencies: is-core-module: 2.15.1 @@ -7695,6 +9796,10 @@ snapshots: reusify@1.0.4: {} + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + rimraf@3.0.2: dependencies: glob: 7.2.3 @@ -7721,6 +9826,31 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.21.0 fsevents: 2.3.3 + rollup@4.36.0: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.36.0 + '@rollup/rollup-android-arm64': 4.36.0 + '@rollup/rollup-darwin-arm64': 4.36.0 + '@rollup/rollup-darwin-x64': 4.36.0 + '@rollup/rollup-freebsd-arm64': 4.36.0 + '@rollup/rollup-freebsd-x64': 4.36.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.36.0 + '@rollup/rollup-linux-arm-musleabihf': 4.36.0 + '@rollup/rollup-linux-arm64-gnu': 4.36.0 + '@rollup/rollup-linux-arm64-musl': 4.36.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.36.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.36.0 + '@rollup/rollup-linux-riscv64-gnu': 4.36.0 + '@rollup/rollup-linux-s390x-gnu': 4.36.0 + '@rollup/rollup-linux-x64-gnu': 4.36.0 + '@rollup/rollup-linux-x64-musl': 4.36.0 + '@rollup/rollup-win32-arm64-msvc': 4.36.0 + '@rollup/rollup-win32-ia32-msvc': 4.36.0 + '@rollup/rollup-win32-x64-msvc': 4.36.0 + fsevents: 2.3.3 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -7744,6 +9874,10 @@ snapshots: safer-buffer@2.1.2: {} + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -7754,6 +9888,8 @@ snapshots: semver@7.6.3: {} + semver@7.7.1: {} + serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -7795,6 +9931,8 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.2 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -7807,7 +9945,10 @@ snapshots: dependencies: semver: 7.6.3 - sisteransi@1.0.5: {} + sisteransi@1.0.5: + optional: true + + slash@2.0.0: {} slash@3.0.0: {} @@ -7826,12 +9967,16 @@ snapshots: semver: 7.6.3 sort-object-keys: 1.1.3 + source-map-js@1.2.1: {} + source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 + optional: true - source-map@0.6.1: {} + source-map@0.6.1: + optional: true source-map@0.8.0-beta.0: dependencies: @@ -7864,6 +10009,8 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + stackback@0.0.2: {} + starknet@6.11.0: dependencies: '@noble/curves': 1.4.2 @@ -7876,12 +10023,32 @@ snapshots: isomorphic-fetch: 3.0.0 lossless-json: 4.0.1 pako: 2.1.0 - starknet-types-07: '@starknet-io/types-js@0.7.7' + starknet-types-07: '@starknet-io/types-js@0.7.10' ts-mixer: 6.0.4 url-join: 4.0.1 transitivePeerDependencies: - encoding + starknet@6.23.1: + dependencies: + '@noble/curves': 1.7.0 + '@noble/hashes': 1.6.0 + '@scure/base': 1.2.1 + '@scure/starknet': 1.1.0 + abi-wan-kanabi: 2.2.3 + fetch-cookie: 3.0.1 + isomorphic-fetch: 3.0.0 + lossless-json: 4.0.1 + pako: 2.1.0 + starknet-types-07: '@starknet-io/types-js@0.7.10' + ts-mixer: 6.0.4 + transitivePeerDependencies: + - encoding + + std-env@3.7.0: {} + + std-env@3.8.1: {} + stop-iteration-iterator@1.0.0: dependencies: internal-slot: 1.0.7 @@ -7890,6 +10057,7 @@ snapshots: dependencies: char-regex: 1.0.2 strip-ansi: 6.0.1 + optional: true string-width@4.2.3: dependencies: @@ -7961,10 +10129,13 @@ snapshots: strip-bom@3.0.0: {} - strip-bom@4.0.0: {} + strip-bom@4.0.0: + optional: true strip-final-newline@2.0.0: {} + strip-final-newline@3.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -7995,6 +10166,8 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + symbol-tree@3.2.4: {} + synckit@0.9.1: dependencies: '@pkgr/core': 0.1.1 @@ -8009,6 +10182,7 @@ snapshots: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 minimatch: 3.1.2 + optional: true text-hex@1.0.0: {} @@ -8022,11 +10196,24 @@ snapshots: dependencies: any-promise: 1.3.0 + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinypool@1.0.1: {} + + tinypool@1.0.2: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 - tmpl@1.0.5: {} + tmpl@1.0.5: + optional: true to-fast-properties@2.0.0: {} @@ -8049,6 +10236,10 @@ snapshots: dependencies: punycode: 2.3.1 + tr46@3.0.0: + dependencies: + punycode: 2.3.1 + tree-kill@1.2.2: {} triple-beam@1.4.1: {} @@ -8059,26 +10250,6 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(esbuild@0.20.2)(jest@29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)))(typescript@5.5.4): - dependencies: - bs-logger: 0.2.6 - ejs: 3.1.10 - fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.16.1)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4)) - jest-util: 29.7.0 - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.6.3 - typescript: 5.5.4 - yargs-parser: 21.1.1 - optionalDependencies: - '@babel/core': 7.25.2 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.25.2) - esbuild: 0.20.2 - ts-mixer@6.0.4: {} ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4): @@ -8099,6 +10270,24 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + ts-node@10.9.2(@types/node@22.13.10)(typescript@5.5.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.13.10 + acorn: 8.12.1 + acorn-walk: 8.3.3 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -8110,7 +10299,7 @@ snapshots: tslib@2.7.0: {} - tsup@8.2.4(tsx@4.17.0)(typescript@5.5.4): + tsup@8.2.4(postcss@8.5.3)(tsx@4.17.0)(typescript@5.5.4)(yaml@2.5.1): dependencies: bundle-require: 5.0.0(esbuild@0.23.1) cac: 6.7.14 @@ -8122,13 +10311,14 @@ snapshots: globby: 11.1.0 joycon: 3.1.1 picocolors: 1.0.1 - postcss-load-config: 6.0.1(tsx@4.17.0) + postcss-load-config: 6.0.1(postcss@8.5.3)(tsx@4.17.0)(yaml@2.5.1) resolve-from: 5.0.0 rollup: 4.21.0 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 optionalDependencies: + postcss: 8.5.3 typescript: 5.5.4 transitivePeerDependencies: - jiti @@ -8148,32 +10338,32 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - turbo-darwin-64@1.13.4: + turbo-darwin-64@2.1.3: optional: true - turbo-darwin-arm64@1.13.4: + turbo-darwin-arm64@2.1.3: optional: true - turbo-linux-64@1.13.4: + turbo-linux-64@2.1.3: optional: true - turbo-linux-arm64@1.13.4: + turbo-linux-arm64@2.1.3: optional: true - turbo-windows-64@1.13.4: + turbo-windows-64@2.1.3: optional: true - turbo-windows-arm64@1.13.4: + turbo-windows-arm64@2.1.3: optional: true - turbo@1.13.4: + turbo@2.1.3: optionalDependencies: - turbo-darwin-64: 1.13.4 - turbo-darwin-arm64: 1.13.4 - turbo-linux-64: 1.13.4 - turbo-linux-arm64: 1.13.4 - turbo-windows-64: 1.13.4 - turbo-windows-arm64: 1.13.4 + turbo-darwin-64: 2.1.3 + turbo-darwin-arm64: 2.1.3 + turbo-linux-64: 2.1.3 + turbo-linux-arm64: 2.1.3 + turbo-windows-64: 2.1.3 + turbo-windows-arm64: 2.1.3 type-check@0.4.0: dependencies: @@ -8183,7 +10373,8 @@ snapshots: type-fest@0.20.2: {} - type-fest@0.21.3: {} + type-fest@0.21.3: + optional: true type-fest@0.6.0: {} @@ -8223,6 +10414,8 @@ snapshots: typescript@5.5.4: {} + typescript@5.8.2: {} + unbox-primitive@1.0.2: dependencies: call-bind: 1.0.7 @@ -8236,6 +10429,8 @@ snapshots: undici-types@6.19.8: {} + undici-types@6.20.0: {} + universalify@0.1.2: {} universalify@0.2.0: {} @@ -8248,6 +10443,13 @@ snapshots: escalade: 3.1.2 picocolors: 1.0.1 + update-browserslist-db@1.1.3(browserslist@4.24.4): + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 + optional: true + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -8268,20 +10470,21 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + optional: true validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - viem@2.20.0(typescript@5.5.4)(zod@3.23.8): + viem@2.20.0(typescript@5.5.4)(zod@3.24.2): dependencies: '@adraffy/ens-normalize': 1.10.0 '@noble/curves': 1.4.0 '@noble/hashes': 1.4.0 '@scure/bip32': 1.4.0 '@scure/bip39': 1.3.0 - abitype: 1.0.5(typescript@5.5.4)(zod@3.23.8) + abitype: 1.0.5(typescript@5.5.4)(zod@3.24.2) isows: 1.0.4(ws@8.17.1) webauthn-p256: 0.0.5 ws: 8.17.1 @@ -8292,9 +10495,155 @@ snapshots: - utf-8-validate - zod + viem@2.23.11(typescript@5.8.2)(zod@3.24.2): + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.2)(zod@3.24.2) + isows: 1.0.6(ws@8.18.1) + ox: 0.6.9(typescript@5.8.2)(zod@3.24.2) + ws: 8.18.1 + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite-node@2.0.5(@types/node@20.16.1): + dependencies: + cac: 6.7.14 + debug: 4.3.6(supports-color@5.5.0) + pathe: 1.1.2 + tinyrainbow: 1.2.0 + vite: 5.4.3(@types/node@20.16.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite-node@2.1.9(@types/node@22.13.10): + dependencies: + cac: 6.7.14 + debug: 4.4.0(supports-color@5.5.0) + es-module-lexer: 1.6.0 + pathe: 1.1.2 + vite: 5.4.14(@types/node@22.13.10) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.14(@types/node@22.13.10): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.36.0 + optionalDependencies: + '@types/node': 22.13.10 + fsevents: 2.3.3 + + vite@5.4.3(@types/node@20.16.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.45 + rollup: 4.21.0 + optionalDependencies: + '@types/node': 20.16.1 + fsevents: 2.3.3 + + vitest@2.0.5(@types/node@20.16.1)(jsdom@20.0.3): + dependencies: + '@ampproject/remapping': 2.3.0 + '@vitest/expect': 2.0.5 + '@vitest/pretty-format': 2.0.5 + '@vitest/runner': 2.0.5 + '@vitest/snapshot': 2.0.5 + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.1.1 + debug: 4.3.6(supports-color@5.5.0) + execa: 8.0.1 + magic-string: 0.30.11 + pathe: 1.1.2 + std-env: 3.7.0 + tinybench: 2.9.0 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.4.3(@types/node@20.16.1) + vite-node: 2.0.5(@types/node@20.16.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.16.1 + jsdom: 20.0.3 + transitivePeerDependencies: + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vitest@2.1.9(@types/node@22.13.10)(jsdom@20.0.3): + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(vite@5.4.14(@types/node@22.13.10)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.2.0 + debug: 4.4.0(supports-color@5.5.0) + expect-type: 1.2.0 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.8.1 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.14(@types/node@22.13.10) + vite-node: 2.1.9(@types/node@22.13.10) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.13.10 + jsdom: 20.0.3 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + w3c-xmlserializer@4.0.0: + dependencies: + xml-name-validator: 4.0.0 + walker@1.0.8: dependencies: makeerror: 1.0.12 + optional: true web-streams-polyfill@3.3.3: {} @@ -8307,8 +10656,21 @@ snapshots: webidl-conversions@4.0.2: {} + webidl-conversions@7.0.0: {} + + whatwg-encoding@2.0.0: + dependencies: + iconv-lite: 0.6.3 + whatwg-fetch@3.6.20: {} + whatwg-mimetype@3.0.0: {} + + whatwg-url@11.0.0: + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -8350,11 +10712,6 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.3 - which-pm@2.2.0: - dependencies: - load-yaml-file: 0.2.0 - path-exists: 4.0.0 - which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 @@ -8371,6 +10728,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + winston-transport@4.7.1: dependencies: logform: 2.6.1 @@ -8413,15 +10775,24 @@ snapshots: dependencies: imurmurhash: 0.1.4 signal-exit: 3.0.7 + optional: true ws@8.17.1: {} + ws@8.18.1: {} + + xml-name-validator@4.0.0: {} + + xmlchars@2.2.0: {} + y18n@5.0.8: {} yallist@2.1.2: {} yallist@3.1.1: {} + yaml@2.5.1: {} + yargs-parser@20.2.9: {} yargs-parser@21.1.1: {} @@ -8458,3 +10829,5 @@ snapshots: yocto-queue@0.1.0: {} zod@3.23.8: {} + + zod@3.24.2: {} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index a56a283d2..d0a2aafa6 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.80.1" +channel = "1.80.1" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c03bdcd4f..902b6ac87 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,3 +19,7 @@ pub mod diri { pub mod sana { pub use sana::*; } + +pub mod orderbook { + pub use orderbook::*; +} diff --git a/turbo.json b/turbo.json index f03f88b17..7d1e4eb01 100644 --- a/turbo.json +++ b/turbo.json @@ -3,10 +3,7 @@ "globalDependencies": [ "**/.env.*local" ], - "globalDotEnv": [ - ".env" - ], - "pipeline": { + "tasks": { "build:packages": { "dependsOn": [ "^build" @@ -60,7 +57,7 @@ }, "test": { "dependsOn": [ - "^test" + "^build" ] }, "lint:fix": { @@ -102,19 +99,11 @@ }, "globalEnv": [ "ACCOUNT_CLASS_HASH", - "ARKCHAIN_RPC_URL", - "BROKER_ID", - "NEXT_PUBLIC_BROKER_ID", - "NEXT_PUBLIC_NFT_API_KEY", - "NEXT_PUBLIC_NFT_API_URL", - "NEXT_PUBLIC_ORDERBOOK_API_URL", - "NEXT_PUBLIC_STARKNET_NFT_CONTRACT", - "ORDERBOOK_CONTRACT", + "CI", "SOLIS_ACCOUNT_CLASS_HASH", "SOLIS_ADMIN_ADDRESS", "SOLIS_ADMIN_ADDRESS_DEV", "SOLIS_ADMIN_PRIVATE_KEY", - "SOLIS_NETWORK_ID", "SOLIS_NODE_URL", "STARKNET_ACCOUNT1_ADDRESS", "STARKNET_ACCOUNT1_PRIVATE_KEY", @@ -130,11 +119,12 @@ "STARKNET_RPC_URL", "STARKNET_ADMIN_PRIVATE_KEY", "STARKNET_ADMIN_ADDRESS", - "SOLIS_ADMIN_PUBLIC_KEY_DEV", - "SOLIS_ADMIN_ADDRESS_SEPOLIA", - "SOLIS_ADMIN_PRIVATE_KEY_SEPOLIA", - "SOLIS_ADMIN_PUBLIC_KEY_SEPOLIA", - "SOLIS_ADMIN_PUBLIC_KEY_MAINNET", - "SOLIS_NODE_URL_SEPOLIA" + "STARKNET_NODE_URL_DEV", + "STARKNET_NODE_URL_MAINNET", + "STARKNET_NODE_URL_SEPOLIA", + "STARKNET_ADMIN_ADDRESS_SEPOLIA", + "STARKNET_ADMIN_PRIVATE_KEY_SEPOLIA", + "STARKNET_ADMIN_ADDRESS_MAINNET", + "STARKNET_ADMIN_PRIVATE_KEY_MAINNET" ] } \ No newline at end of file