diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index aebd4998..68e8a6ea 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -41,11 +41,11 @@ jobs: repository: district0x/ethlance-config path: ethlance-config token: ${{ secrets.ETHLANCE_CONFIG_PAT }} - ref: master + ref: docker_build - name: Run ganache service run: | - docker run --rm -d --name ganache -p 8550:8550 trufflesuite/ganache:v7.9.1 -v -m "easy leave proof verb wait patient fringe laptop intact opera slab shine" -p 8550 -b 0.5 --chain.allowUnlimitedContractSize=true + docker run --rm -d --name ganache -p 8550:8550 trufflesuite/ganache:v7.9.1 -v -m '${{vars.ETHLANCE_DEPLOY_SEED}}' -p 8550 -b 0.5 --chain.allowUnlimitedContractSize=true - name: Restore Top level cache directory for Ethlance uses: actions/cache@v3 @@ -76,6 +76,8 @@ jobs: cd .. - name: Deploy contracts to ganache-test + env: + ETHLANCE_DEPLOY_SEED: ${{ vars.ETHLANCE_DEPLOY_SEED }} run: | npx truffle migrate --network ganache-test --reset diff --git a/.gitignore b/.gitignore index b74cf67d..39a9612f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ node_modules .cpcache ui/out/** server/out/** +server/out-syncer/** yarn-error.log ui/resources/public/js ui/resources/public/css diff --git a/bb.edn b/bb.edn index 21e4319a..42ea4e88 100644 --- a/bb.edn +++ b/bb.edn @@ -43,6 +43,12 @@ command-args (format "-A:dev:shadow-cljs%s watch dev-server" (clojure.string.join "" aliases))] (println "Starting watch dev-server args:" command-args) (clojure {:dir "server"} command-args))} + watch-syncer {:doc "Watch and compile syncer code changes CLJS -> JS in server/src/ethlance/server/syncer*" + :requires ([babashka.cli :as cli]) + :task (let [aliases (or *command-line-args* []) + command-args (format "-A:dev:shadow-cljs%s watch new-syncer" (clojure.string.join "" aliases))] + (println "Starting watch dev-server args:" command-args) + (clojure {:dir "server"} command-args))} run-server {:doc "Start Node.js API server process" :task (do (println "Starting Ethlance API server") @@ -60,6 +66,7 @@ [build-id folder] (case build-arg "ui" [:dev-ui "ui"] "server" [:dev-server "server"] + "syncer" [:new-syncer "server"] "test" [:test-repl "server"]) _ (println ">>> build-id folder" build-id folder) parse-port (fn [folder] (get-in (clojure.edn/read-string (slurp (str folder "/shadow-cljs.edn"))) [:nrepl :port])) diff --git a/docker-builds/base/Dockerfile b/docker-builds/base/Dockerfile index bd42ebdc..5c4b6ca0 100644 --- a/docker-builds/base/Dockerfile +++ b/docker-builds/base/Dockerfile @@ -1,5 +1,5 @@ ARG BUILD_ENV=qa -FROM --platform=amd64 487920318758.dkr.ecr.us-west-2.amazonaws.com/cljs-web3-ci:node-18.17.0 +FROM --platform=amd64 487920318758.dkr.ecr.us-west-2.amazonaws.com/cljs-web3-ci:node-18.20.1 USER root RUN npm i -g truffle@v5.11 @@ -12,7 +12,7 @@ WORKDIR /build/ethlance COPY . . WORKDIR /build/ethlance-config -COPY config . +COPY ethlance-config . WORKDIR /build RUN git clone https://github.com/district0x/d0x-libs diff --git a/docker-builds/server/Dockerfile b/docker-builds/server/Dockerfile index d09d9d61..966ddd99 100644 --- a/docker-builds/server/Dockerfile +++ b/docker-builds/server/Dockerfile @@ -1,5 +1,6 @@ -FROM --platform=amd64 487920318758.dkr.ecr.us-west-2.amazonaws.com/cljs-web3-ci:node-18.17.0 as init +FROM --platform=amd64 487920318758.dkr.ecr.us-west-2.amazonaws.com/cljs-web3-ci:node-18.20.1 as init ARG BUILD_ENV=qa +ARG ETHLANCE_DEPLOY_SEED="sign bachelor state zoo expire boat morning situate scene unveil oven crew" USER root ENV ETHLANCE_COMPONENT="server" @@ -7,6 +8,7 @@ ENV ETHLANCE_SOURCE_ROOT=/build/ethlance ENV ETHLANCE_SERVER_ROOT=/build/ethlance/server ENV ETHLANCE_ENV=$BUILD_ENV ENV DEPLOY_TARGET=/deploy/ +ENV ETHLANCE_DEPLOY_SEED=${ETHLANCE_DEPLOY_SEED} ENV SMART_CONTRACTS_PATH="/build/ethlance/shared/src/ethlance/shared/smart_contracts_${BUILD_ENV}.cljs" ENV SMART_CONTRACTS_BUILD_PATH="/build/ethlance/resources/public/contracts/build" @@ -18,18 +20,19 @@ COPY . . RUN cat "${SMART_CONTRACTS_PATH}" -WORKDIR /build/ethlance-config -COPY config . - +# WORKDIR /build/ethlance-config/ +# COPY ethlance-config . WORKDIR /build -# RUN git clone https://github.com/district0x/d0x-libs +COPY ethlance-config/config /build/ethlance/config +# RUN cp /build/ethlance/ethlance-config/config /build/ethlance/ +RUN git clone https://github.com/district0x/d0x-libs FROM init as build_server -WORKDIR $ETHLANCE_SOURCE_ROOT +WORKDIR ${ETHLANCE_SOURCE_ROOT} RUN yarn install && ETHLANCE_ENV="${BUILD_ENV}" npx truffle compile # Release deployment -WORKDIR $ETHLANCE_SOURCE_ROOT/ui +WORKDIR "${ETHLANCE_SOURCE_ROOT}/ui" RUN yarn && \ ETHLANCE_ENV="${BUILD_ENV}" npx shadow-cljs release dev-ui && \ ./node_modules/less/bin/lessc resources/public/less/main.less resources/public/css/main.css --verbose @@ -49,8 +52,8 @@ ENV UI_CONFIG_PATH="/deploy/resources/config/ui-config-${BUILD_ENV}.edn" ENV SERVER_CONFIG_PATH="/deploy/resources/config/server-config-${BUILD_ENV}.edn" WORKDIR "${ETHLANCE_SERVER_ROOT}" -COPY --from=build_server /build/ethlance-config/ui-config-${ETHLANCE_ENV}.edn /deploy/resources/config/ui-config-${ETHLANCE_ENV}.edn -COPY --from=build_server /build/ethlance-config/server-config-${ETHLANCE_ENV}.edn /deploy/resources/config/server-config-${ETHLANCE_ENV}.edn +COPY --from=build_server /build/ethlance/config/ui-config-${ETHLANCE_ENV}.edn /deploy/resources/config/ui-config-${ETHLANCE_ENV}.edn +COPY --from=build_server /build/ethlance/config/server-config-${ETHLANCE_ENV}.edn /deploy/resources/config/server-config-${ETHLANCE_ENV}.edn COPY --from=build_server /build/ethlance/resources /deploy/resources COPY --from=build_server /build/ethlance/server/node_modules /deploy/server/node_modules/ COPY --from=build_server /build/ethlance/server/package.json /build/ethlance/server/out/ethlance_server* /deploy/server/ diff --git a/docker-builds/ui/Dockerfile b/docker-builds/ui/Dockerfile index d335e87a..a53e66a7 100644 --- a/docker-builds/ui/Dockerfile +++ b/docker-builds/ui/Dockerfile @@ -1,5 +1,6 @@ -FROM --platform=amd64 487920318758.dkr.ecr.us-west-2.amazonaws.com/cljs-web3-ci:node-18.17.0 as init +FROM --platform=amd64 487920318758.dkr.ecr.us-west-2.amazonaws.com/cljs-web3-ci:node-18.20.1 as init ARG BUILD_ENV=qa +ARG ETHLANCE_DEPLOY_SEED="sign bachelor state zoo expire boat morning situate scene unveil oven crew" USER root ENV ETHLANCE_COMPONENT="ui" @@ -7,7 +8,7 @@ ENV ETHLANCE_SOURCE_ROOT=/build/ethlance ENV ETHLANCE_SERVER_ROOT=/build/ethlance/server ENV ETHLANCE_ENV=$BUILD_ENV ENV DEPLOY_TARGET=/deploy/ - +ENV ETHLANCE_DEPLOY_SEED="${ETHLANCE_DEPLOY_SEED}" ENV SMART_CONTRACTS_PATH="/build/ethlance/shared/src/ethlance/shared/smart_contracts_${BUILD_ENV}.cljs" ENV SMART_CONTRACTS_BUILD_PATH="/build/ethlance/resources/public/contracts/build" ENV ETHLANCE_CONFIG_PATH="/build/ethlance/config/${ETHLANCE_COMPONENT}-config-${BUILD_ENV}.edn" @@ -15,15 +16,18 @@ ENV ETHLANCE_CONFIG_PATH="/build/ethlance/config/${ETHLANCE_COMPONENT}-config-${ WORKDIR /build/ethlance COPY . . -RUN cat shared/src/ethlance/shared/smart_contracts_${ETHLANCE_ENV}.cljs +RUN cat "${SMART_CONTRACTS_PATH}" -WORKDIR /build/ethlance-config -COPY config . +# WORKDIR /build/ethlance-config +# COPY config . -# WORKDIR /build -# RUN git clone https://github.com/district0x/d0x-libs +WORKDIR /build +COPY ethlance-config/config /build/ethlance/config +RUN git clone https://github.com/district0x/d0x-libs +ARG BUILD_ENV=qa +ARG ETHLANCE_ENV=qa FROM init as build_stage ENV ETHLANCE_ENV=qa WORKDIR $ETHLANCE_SOURCE_ROOT diff --git a/migrations/2_unchangeable_and_proxy_contracts.js b/migrations/2_unchangeable_and_proxy_contracts.js index 9d6f3cda..7ba3013e 100644 --- a/migrations/2_unchangeable_and_proxy_contracts.js +++ b/migrations/2_unchangeable_and_proxy_contracts.js @@ -14,8 +14,16 @@ let Job = artifacts.require("Job"); let EthlanceStructs = artifacts.require("EthlanceStructs"); let EthlanceProxy = artifacts.require("EthlanceProxy"); let MutableForwarder = artifacts.require("MutableForwarder"); -// copy("EthlanceProxy", "EthlanceProxy", contracts_build_directory); -// let EthlanceProxy = artifacts.require("EthlanceProxy"); + +let deployedContracts = {}; + +function getDeployedAddress(contractName) { + const address = deployedContracts[contractName]; + if (address == null) { + throw new Error("Contract with" + contractName + " not founc in deployedContracts"); + } + return address; +} // Deployment Functions @@ -54,7 +62,8 @@ async function deploy_EthlanceStructs(deployer, opts){ async function deploy_JobHelpers(deployer, opts){ let jobHelpers = await deployer.deploy(JobHelpers, {...opts, gas: 6e6}); - deployer.link(JobHelpers, Job); + // Linking to Job to be done in deploy_Job() + // deployer.link(JobHelpers, Job); assignContract(jobHelpers, "JobHelpers", "job-helpers"); } @@ -67,6 +76,10 @@ async function deploy_proxies(deployer, opts) { } async function deploy_Job(deployer, opts){ + jobHelpersInstance = await JobHelpers.at(getDeployedAddress("JobHelpers")); + ethlanceStructsInstance = await EthlanceStructs.at(getDeployedAddress("EthlanceStructs")); + deployer.link(jobHelpersInstance, Job); + deployer.link(ethlanceStructsInstance, Job); let job = await deployer.deploy(Job, {...opts, gas: 18e6}); assignContract(job, "Job", "job"); } @@ -77,6 +90,7 @@ async function deploy_all(deployer, opts) { await deploy_TestMultiToken(deployer, opts); await deploy_EthlanceStructs(deployer, opts); await deploy_JobHelpers(deployer, opts); + await deploy_Job(deployer, opts); await deploy_proxies(deployer, opts); } @@ -93,6 +107,7 @@ let smart_contract_listing = []; */ function assignContract(contract_instance, contract_name, contract_key, opts) { console.log("- Assigning '" + contract_name + "' to smart contract listing..."); + deployedContracts[contract_name] = contract_instance.address; opts = opts || {}; smart_contract_listing = smart_contract_listing.concat( encodeContractEDN(contract_instance, contract_name, contract_key, opts)); @@ -114,6 +129,7 @@ function writeSmartContracts() { // module.exports = async function(deployer, network, accounts) { const gas = 4e6; + console.log("Deploying FROM:", deployer.options.from); const from = deployer.options.from || accounts[0]; const opts = {gas: gas, from: from}; diff --git a/migrations/3_ethlance_initial_implementation.js b/migrations/3_ethlance_initial_implementation.js index 535c6152..acb2ef5e 100644 --- a/migrations/3_ethlance_initial_implementation.js +++ b/migrations/3_ethlance_initial_implementation.js @@ -1,5 +1,6 @@ const edn = require ("jsedn"); const {env, smart_contracts_path, contracts_build_directory} = require ('../truffle-config.js'); +console.log(">>> Migra 3: env", env); const {copy, encodeContractEDN, readSmartContractsFile, getSmartContractAddress, setSmartContractAddress, writeSmartContracts, setSmartContractForwardsTo, linkBytecode} = require("./utils"); const Ethlance = artifacts.require("Ethlance"); diff --git a/server/deps.edn b/server/deps.edn index 16a59188..eb4b6a42 100644 --- a/server/deps.edn +++ b/server/deps.edn @@ -1,7 +1,7 @@ -{:paths ["src" "test"] +{:paths ["src"] :deps - {org.clojure/clojure {:mvn/version "1.10.3"}, - org.clojure/clojurescript {:mvn/version "1.11.60"} + {org.clojure/clojure {:mvn/version "1.12.0"}, + org.clojure/clojurescript {:mvn/version "1.11.132"} is.d0x/ethlance-shared {:local/root "../shared"} mvxcvi/alphabase {:mvn/version "2.1.1"} @@ -60,7 +60,7 @@ :aliases {:shadow-cljs {:extra-deps - {thheller/shadow-cljs {:mvn/version "2.26.2"}} + {thheller/shadow-cljs {:mvn/version "2.28.16"}} :main-opts ["-m" "shadow.cljs.devtools.cli"]} :local-deps {:override-deps @@ -76,4 +76,6 @@ {; Vim Iced deps refactor-nrepl/refactor-nrepl {:mvn/version "3.3.2"} cider/cider-nrepl {:mvn/version "0.28.2"} - com.github.liquidz/iced-nrepl {:mvn/version "1.2.8"}}}}} + com.github.liquidz/iced-nrepl {:mvn/version "1.2.8"}}} + :test + {:extra-paths ["test"]}}} diff --git a/server/package.json b/server/package.json index 03f9c86d..bc0aa6a3 100644 --- a/server/package.json +++ b/server/package.json @@ -23,11 +23,12 @@ "graphql": "14.2.1", "graphql-middleware": "4.0.1", "graphql-tools": "4.0.5", + "@helia/verified-fetch": "1.5.0", "is-ipfs": "2.0.0", "jsedn": "0.4.1", "jsonwebtoken": "8.5.1", "pg": "8.8.0", - "shadow-cljs": "2.26.2", + "shadow-cljs": "2.28.16", "web3": "1.7.3", "ws": "4.0.0", "xhr2": "0.2.1", diff --git a/server/shadow-cljs.edn b/server/shadow-cljs.edn index 600e2b99..14241141 100644 --- a/server/shadow-cljs.edn +++ b/server/shadow-cljs.edn @@ -18,6 +18,19 @@ {:compiler-options {:optimizations :simple :source-map true}}} + :new-syncer + {:target :node-script + :main ethlance.server.new-syncer/-main + :output-dir "out-syncer/" + :output-to "out-syncer/new-syncer.js" + :optimizations :none + :source-map true + :source-map-timestamp true + :closure-defines {goog.DEBUG true} + + :release + {:compiler-options {:optimizations :simple + :source-map true}}} :server-tests {:target :node-test :js-options {:js-package-dirs ["./server/node_modules"]} diff --git a/server/src/ethlance/server/config.cljs b/server/src/ethlance/server/config.cljs new file mode 100644 index 00000000..f0f1bf07 --- /dev/null +++ b/server/src/ethlance/server/config.cljs @@ -0,0 +1,82 @@ +(ns ethlance.server.config + (:require + [ethlance.server.db :as server-db] + [ethlance.server.new-syncer.handlers :as new-syncer.handlers] + [ethlance.server.new-syncer :as new-syncer] + [ethlance.shared.config :as shared-config] + [ethlance.shared.smart-contracts-dev :as smart-contracts-dev] + [ethlance.shared.smart-contracts-prod :as smart-contracts-prod] + [ethlance.shared.smart-contracts-qa :as smart-contracts-qa] + [ethlance.shared.smart-contracts-qa-base :as smart-contracts-qa-base] + [ethlance.shared.utils :include-macros true :as shared-utils] + )) + + +(def environment (shared-utils/get-environment)) + +(println "Ethlance server starting in environment:" environment) + + +(def contracts-var + (condp = environment + "prod" #'smart-contracts-prod/smart-contracts + "qa" #'smart-contracts-qa/smart-contracts + "qa-base" #'smart-contracts-qa-base/smart-contracts + "dev" #'smart-contracts-dev/smart-contracts + ; "dev" #'smart-contracts-qa-base/smart-contracts + )) + + +(def default-config + {:web3 {:url "ws://127.0.0.1:8549"} + :new-syncer {:auto-start-listening-new-events? false + :handlers new-syncer.handlers/handlers + :save-checkpoint server-db/save-processed-events-checkpoint} + :web3-events {:events + {:ethlance/job-created [:ethlance :JobCreated] + :ethlance/invoice-created [:ethlance :InvoiceCreated] + :ethlance/invoice-paid [:ethlance :InvoicePaid] + :ethlance/dispute-raised [:ethlance :DisputeRaised] + :ethlance/dispute-resolved [:ethlance :DisputeResolved] + :ethlance/candidate-added [:ethlance :CandidateAdded] + :ethlance/quote-for-arbitration-set [:ethlance :QuoteForArbitrationSet] + :ethlance/quote-for-arbitration-accepted [:ethlance :QuoteForArbitrationAccepted] + :ethlance/job-ended [:ethlance :JobEnded] + :ethlance/arbiters-invited [:ethlance :ArbitersInvited] + :ethlance/funds-in [:ethlance :FundsIn] + :ethlance/funds-out [:ethlance :FundsOut] + :ethlance/test-event [:ethlance :TestEvent]} + :from-block 1000 + :block-step 5 ; 1000 + :dispatch-logging? true + :crash-on-event-fail? true + :skip-past-events-replay? false + :load-checkpoint server-db/load-processed-events-checkpoint + :save-checkpoint server-db/save-processed-events-checkpoint + :callback-after-past-events new-syncer/start-listening-new-events + } + :smart-contracts {:contracts-var contracts-var + :contracts-build-path "../resources/public/contracts/build" + :print-gas-usage? false + :auto-mining? false} + :graphql {:port 6300 + :sign-in-secret "SECRET" + :graphiql (= environment "dev")} + :district/db {:user "ethlanceuser" + :host "localhost" + :database "ethlance" + :password "pass" + :port 5432} + :ethlance/db {:resync? false} + :ipfs {:host "http://host-machine:5001" + :endpoint "/api/v0" + :gateway "http://host-machine:8080/ipfs"} + :logging {:level "debug" + :console? true}}) + + +(defn env-config + [_env] + (shared-utils/deep-merge + default-config + shared-config/config)) diff --git a/server/src/ethlance/server/core.cljs b/server/src/ethlance/server/core.cljs index 6faa3980..997f4512 100644 --- a/server/src/ethlance/server/core.cljs +++ b/server/src/ethlance/server/core.cljs @@ -2,7 +2,7 @@ (:require ["fs" :as fs] [district.server.async-db] - [district.server.config :refer [config]] + [district.server.config :as district-config] [district.server.db] [district.server.db.honeysql-extensions] [district.server.logging] @@ -11,93 +11,16 @@ [district.server.web3] [district.server.web3-events] [district.shared.async-helpers :as async-helpers :refer [safe-go]] + [ethlance.server.config :as server-config] [ethlance.server.db] [ethlance.server.graphql.server] [ethlance.server.ipfs] [ethlance.server.syncer] - [ethlance.shared.config :as shared-config] - [ethlance.shared.smart-contracts-dev :as smart-contracts-dev] - [ethlance.shared.smart-contracts-prod :as smart-contracts-prod] - [ethlance.shared.smart-contracts-qa :as smart-contracts-qa] - [ethlance.shared.utils :include-macros true :as shared-utils] + [ethlance.server.new-syncer] [mount.core :as mount] [taoensso.timbre :refer [merge-config!] :as log])) -(def environment (shared-utils/get-environment)) - -(println "Ethlance server starting in environment:" environment) - - -(def contracts-var - (condp = environment - "prod" #'smart-contracts-prod/smart-contracts - "qa" #'smart-contracts-qa/smart-contracts - "dev" #'smart-contracts-dev/smart-contracts)) - - -(def default-config - {:web3 {:url "ws://127.0.0.1:8549"} - :web3-events {:events - {:ethlance/job-created [:ethlance :JobCreated] - :ethlance/invoice-created [:ethlance :InvoiceCreated] - :ethlance/invoice-paid [:ethlance :InvoicePaid] - :ethlance/dispute-raised [:ethlance :DisputeRaised] - :ethlance/dispute-resolved [:ethlance :DisputeResolved] - :ethlance/candidate-added [:ethlance :CandidateAdded] - :ethlance/quote-for-arbitration-set [:ethlance :QuoteForArbitrationSet] - :ethlance/quote-for-arbitration-accepted [:ethlance :QuoteForArbitrationAccepted] - :ethlance/job-ended [:ethlance :JobEnded] - :ethlance/arbiters-invited [:ethlance :ArbitersInvited] - :ethlance/funds-in [:ethlance :FundsIn] - :ethlance/funds-out [:ethlance :FundsOut] - :ethlance/test-event [:ethlance :TestEvent]} - :from-block 1000 - :block-step 5 ; 1000 - :dispatch-logging? true - :crash-on-event-fail? true - :skip-past-events-replay? false - :write-events-into-file? true - :load-checkpoint ethlance.server.db/load-processed-events-checkpoint - :save-checkpoint ethlance.server.db/save-processed-events-checkpoint} - :smart-contracts {:contracts-var contracts-var - :contracts-build-path "../resources/public/contracts/build" - :print-gas-usage? false - :auto-mining? false} - :graphql {:port 6300 - :sign-in-secret "SECRET" - :graphiql (= environment "dev")} - :district/db {:user "ethlanceuser" - :host "localhost" - :database "ethlance" - :password "pass" - :port 5432} - :ethlance/db {:resync? false} - :ipfs {:host "http://host-machine:5001" - :endpoint "/api/v0" - :gateway "http://host-machine:8080/ipfs"} - :logging {:level "debug" - :console? true}}) - - -(def config-dev - {:ipfs - {:host "https://ipfs.infura.io:5001" - :endpoint "/api/v0" - :gateway "https://ethlance-qa.infura-ipfs.io/ipfs" - :auth {:username "xxx" - :password "xxx"}}}) - - -(defn env-config - [env] - (shared-utils/deep-merge - default-config - (if (= env "dev") - config-dev - shared-config/config))) - - (defn -main [& _] (log/info "Initializing Server...") @@ -108,9 +31,9 @@ (let [start-result (-> (mount/with-args {:config {:env-name "SERVER_CONFIG_PATH" - :default (env-config environment)}}) + :default (server-config/env-config server-config/environment)}}) (mount/start))] - (log/warn "Started" {:components start-result :config @config})) + (log/warn "Started" {:components start-result :config @district-config/config})) (catch js/Error e (log/error "Something went wrong when starting the application" {:error e}))))) diff --git a/server/src/ethlance/server/db.cljs b/server/src/ethlance/server/db.cljs index fbc9c996..3dffd735 100644 --- a/server/src/ethlance/server/db.cljs +++ b/server/src/ethlance/server/db.cljs @@ -645,15 +645,21 @@ :token-detail/decimals (:decimals token-details)})))) +(def get-checkpoint-query + {:select [:*] + :from [:ContractEventCheckpoint] + :order-by [[:created-at :desc]]}) + (defn load-processed-events-checkpoint [callback] (.then (district.server.async-db/get-connection) (fn [conn] - (let [result-chan (db/get conn {:select [:*] - :from [:ContractEventCheckpoint] - :order-by [[:created-at :desc]]})] - (take! result-chan (fn [result] (callback nil (clojure.walk/keywordize-keys (get result :checkpoint))))))))) + (let [result-chan (db/get conn get-checkpoint-query)] + (async/take! result-chan + (fn [result] + (println ">>> load-processed-events-checkpoint LOADED" result) + (callback nil (clojure.walk/keywordize-keys (get result :checkpoint))))))))) (defn save-processed-events-checkpoint @@ -661,10 +667,40 @@ (.then (district.server.async-db/get-connection) (fn [conn] - (let [result-chan (db/run! conn {:insert-into :ContractEventCheckpoint - :values [{:checkpoint (.stringify js/JSON (clj->js checkpoint)) - :created-at (new js/Date)}]})] - (when (fn? callback) (take! result-chan callback)))))) + (async/go + (let [old-checkpoint-row ( checkpoint + (dissoc ,,, :started-at) + (assoc :last-processed-block (:last-processed-block checkpoint) + )) + new-checkpoint (if (empty? aggregated-log-indexes) + new-checkpoint + (assoc new-checkpoint :processed-log-indexes aggregated-log-indexes)) + + started-at (or (:started-at checkpoint) (new js/Date)) + insert-query {:insert-into :ContractEventCheckpoint + :values [{:checkpoint (.stringify js/JSON (clj->js new-checkpoint)) + :created-at (new js/Date)}]} + update-query {:update :ContractEventCheckpoint + :set {:checkpoint (.stringify js/JSON (clj->js new-checkpoint))} + :where [:= :id (:id old-checkpoint-row)]} + result-chan (db/run! conn (if (or + (> started-at (:created-at old-checkpoint-row)) + (nil? old-checkpoint)) + insert-query + update-query))] + (district.server.async-db/release-connection conn) + (when (fn? callback) (async/take! result-chan callback))))))) (defn ready-state? diff --git a/server/src/ethlance/server/new_syncer.cljs b/server/src/ethlance/server/new_syncer.cljs new file mode 100644 index 00000000..279e5589 --- /dev/null +++ b/server/src/ethlance/server/new_syncer.cljs @@ -0,0 +1,104 @@ +(ns ethlance.server.new-syncer + (:require + [taoensso.timbre :as log] + ; [ethlance.server.config :as server-config] + ; [district.server.config :as district-config] + [ethlance.server.new-syncer.core :as new-syncer.core] + + [ethlance.server.db] + [ethlance.server.ipfs] + + [clojure.core.async :as async :refer [! go] :include-macros true] + [district.server.config :as server.config] + [ethlance.server.new-syncer.web3-subscribe :as new-syncer.web3-subscribe] + [district.server.async-db :as db :include-macros true] + [mount.core :as mount :refer [defstate]])) + +(declare start stop) + +(defstate new-syncer :start (start @server.config/config) :stop (stop)) +(defonce subscription-started? (atom false)) + +(defn db-context-provider [handler] + (async/go + (let [db-conn (async/>> SYNCER processed: " result) + (println ">>> SYNCER checkpoint: " checkpoint) + (save-checkpoint checkpoint) + (recur))) + + {:start-subscription start-subscription + :started-at started-at + :out-chan out-chan + :syncer syncer})) + +(defn start + [config] + ;; Start the subscription + (log/info "Starting new-syncer. auto-start?" (get-in config [:new-syncer :auto-start-listening-new-events?])) + ; (if (get-in config [:new-syncer :auto-start-listening-new-events?]) + ; (start-syncer config) + ; (log/info "Postponing listening new events due to :auto-start-listening-new-events? false")) + (start-syncer config) + ) + +(defn stop + [] + ;; Stop listening to the events + ) + +(defn start-listening-new-events + [] + (log/info "start-listening-new-events called") + ((:start-subscription @new-syncer))) + +(defn -main + [& _] + (log/info "Initializing new-syncer") + ; (-> + ; (mount/only #{#'ethlance.server.db/ethlance-db + ; #'ethlance.server.ipfs/ipfs}) + ; (mount/with-args + ; {:config + ; {:env-name "SERVER_CONFIG_PATH" + ; :default (server-config/env-config server-config/environment)}}) + ; (mount/start)) + ) diff --git a/server/src/ethlance/server/new_syncer/core.cljs b/server/src/ethlance/server/new_syncer/core.cljs new file mode 100644 index 00000000..806a6785 --- /dev/null +++ b/server/src/ethlance/server/new_syncer/core.cljs @@ -0,0 +1,44 @@ +(ns ethlance.server.new-syncer.core + (:require + ["node:fs" :as fs] + [taoensso.timbre :as log] + [goog.object :as g] + [clojure.core.async :as async :refer [! go] :include-macros true] + [cljs.core.async.impl.protocols :refer [ReadPort]] + [ethlance.server.new-syncer.web3-subscribe :as web3-subscribe])) + + +(defn read-json [path] + (->> path + (.readFileSync fs ,,,) + (.parse js/JSON ,,,))) + + +(defn parse-contract-abi [contract-build-path] + (g/get (read-json contract-build-path) "abi")) + + +(defn do-nothing-handler [_ _ _event] + (println "Doing nothing with" _event)) + +(defn init-syncer + "Starts up go-loop to read from `event-source`, process via handler in `event-handlers` + and puts processing result in a returned channel + + event-source - clojure async channel + event-handlers - map of event name => function of 3 args [context, err, event] + context-provider - a function that gets called with callback whose 1st argument it will put context" + [event-source event-handlers context-provider] + (let [out-chan (async/chan (async/sliding-buffer 1))] + (async/go-loop [] + (let [[error event] (async/! out-chan {:event event :result val-from-chan :name event-name}))) + (recur))) + out-chan)) diff --git a/server/src/ethlance/server/new_syncer/handlers.cljs b/server/src/ethlance/server/new_syncer/handlers.cljs new file mode 100644 index 00000000..b1204f01 --- /dev/null +++ b/server/src/ethlance/server/new_syncer/handlers.cljs @@ -0,0 +1,18 @@ +(ns ethlance.server.new-syncer.handlers + (:require + [ethlance.server.syncer.handlers :as old-syncer])) + +(def handlers + {:JobCreated old-syncer/handle-job-created + :FundsIn (partial old-syncer/handle-job-funds-change +) + :ArbitersInvited old-syncer/handle-arbiters-invited + :CandidateAdded old-syncer/handle-candidate-added + :TestEvent old-syncer/handle-test-event + :InvoiceCreated old-syncer/handle-invoice-created + :InvoicePaid old-syncer/handle-invoice-paid + :DisputeRaised old-syncer/handle-dispute-raised + :DisputeResolved old-syncer/handle-dispute-resolved + :QuoteForArbitrationSet old-syncer/handle-quote-for-arbitration-set + :QuoteForArbitrationAccepted old-syncer/handle-quote-for-arbitration-accepted + :JobEnded old-syncer/handle-job-ended + :FundsOut (partial old-syncer/handle-job-funds-change -)}) diff --git a/server/src/ethlance/server/new_syncer/web3_subscribe.cljs b/server/src/ethlance/server/new_syncer/web3_subscribe.cljs new file mode 100644 index 00000000..141757b3 --- /dev/null +++ b/server/src/ethlance/server/new_syncer/web3_subscribe.cljs @@ -0,0 +1,53 @@ +(ns ethlance.server.new-syncer.web3-subscribe + (:require + [clojure.core.async :as async :refer [clj-map]] + [district.server.smart-contracts :as server.smart-contracts])) + +(defn init-web3 [node-address] + (new Web3 node-address)) + +(defn init-contract [web3 abi address] + (new (.-Contract (.-eth web3)) abi address)) + +(def last-event (atom nil)) +(def seen-events (atom [])) + +(defn record-for-debugging + [err event] + (reset! last-event event) + (let [event-name (g/get event "event") + block-number (g/get event "blockNumber") + tx-hash (g/get event "transactionHash") + return-values (js-obj->clj-map (.-returnValues event)) + event-info {:event-name event-name + :received-at (system-time) + :block-number block-number + :tx-hash tx-hash + :event event + :err err + :return-values return-values}] + (swap! seen-events conj event-info) + (log/info (str "🎯🎯 --> putting event to channel\n" (with-out-str (cljs.pprint/pprint event-info)))))) + +(defn subscribe! + "Takes config and output channel. Then subscribes to Web3.js for all events them to the output channel" + [{:keys [ethereum-node ethlance-abi ethlance-address]} + output] + (log/info "web3-subscribe/subscribe" {:ethereum-node ethereum-node :ethlance-address ethlance-address}) + (let [web3 (init-web3 ethereum-node) + contract (init-contract web3 ethlance-abi ethlance-address)] + ;; Return value of .allEvents is documented at + ;; https://web3js.readthedocs.io/en/v1.8.2/web3-eth-contract.html#contract-events-return + (.allEvents (g/get contract "events") + (fn [err event] + (record-for-debugging err event) + (async/put! output + [err + (->> event + web3-helpers/js->cljkk + (server.smart-contracts/enrich-event-log :ethlance contract ,,,))]))))) diff --git a/server/src/ethlance/server/syncer.cljs b/server/src/ethlance/server/syncer.cljs index 3a171238..2b9b7b94 100644 --- a/server/src/ethlance/server/syncer.cljs +++ b/server/src/ethlance/server/syncer.cljs @@ -8,17 +8,9 @@ [district.server.smart-contracts :as smart-contracts] [district.server.web3-events :as web3-events] [district.shared.async-helpers :refer [flat-map - enum-val->token-type]] - [ethlance.shared.token-utils :as token-utils] - [ethlance.shared.utils :as shared-utils] - [honeysql.core :as sql] + [ethlance.server.syncer.handlers :as handlers] [mount.core :as mount :refer [defstate]] [taoensso.timbre :as log])) @@ -31,313 +23,6 @@ :stop (stop)) -(defn get-timestamp - ([] (get-timestamp {})) - ([_event] (.now js/Date))) - - -(defn build-ethlance-job-data-from-ipfs-object - [ethlance-job-data] - {:job/title (:job/title ethlance-job-data) - :job/description (:job/description ethlance-job-data) - :job/category (:job/category ethlance-job-data) - :job/required-skills (:job/required-skills ethlance-job-data) - :job/required-experience-level (:job/required-experience-level ethlance-job-data) - :job/language-id nil; TODO: where does it come from - :job/bid-option (:job/bid-option ethlance-job-data) - :job/estimated-project-length (:job/estimated-project-length ethlance-job-data) - :job/invitation-only? nil ; TODO: where does it come from - :job/required-availability (:job/required-availability ethlance-job-data)}) - - -(defn ensure-db-token-details - [token-type token-address conn] - (safe-go - (let [eth-token-details {:address "0x0000000000000000000000000000000000000000" - :name "Ether" - :symbol "ETH" - :type :eth - :decimals 18}] - (when (not (>> Handling event job-created" args " | " (t-api/get-active-span))) - (println ">>> ipfs-data | type ipfs-data" {:ipfs-data (:ipfs-data args) :event event}) - (let [span (t-api/get-active-span) - ipfs-hash (shared-utils/hex->base58 (:ipfs-data args)) - ipfs-job-content (flat-map (first (:offered-values args))) - token-address (:token-address offered-value) - token-type (enum-val->token-type (:token-type offered-value)) - token-amount (:token-amount offered-value) - for-the-db (merge {:job/id (:job args) - :job/status "active" ; draft -> active -> finished hiring -> closed - :job/creator (:creator args) - :job/date-created (get-timestamp event) - :job/date-updated (get-timestamp event) - - :job/token-type token-type - :job/token-amount token-amount - :job/token-address token-address - :job/token-id (:token-id offered-value) - :invited-arbiters (get args :invited-arbiters [])} - (build-ethlance-job-data-from-ipfs-object ipfs-job-content))] - (t-api/add-event! span "job-details" {:ipfs-hash ipfs-hash :job-id (:job args) :token-type token-type :token-amount token-amount}) - (t-api/start-active-span - "ensure-token-details" - (fn [span] - (go! - (base58 (:ipfs-data args)))) - job-story-id (:job-story/id ipfs-data) - invoicer (:invoicer args) - offered-value (offered-vec->flat-map (first (:invoiced-value args))) - invoice-message {:job-story/id job-story-id - :message/type :job-story-message - :job-story-message/type :invoice - :message/text (:message/text ipfs-data) - :message/creator invoicer - :message/date-created (get-timestamp) - :invoice/date-requested (get-timestamp) - :invoice/status "created" - :invoice/amount-requested (:token-amount offered-value) - :invoice/hours-worked (:invoice/hours-worked ipfs-data) - :invoice/hourly-rate (:invoice/hourly-rate ipfs-data) - :invoice/ref-id (:invoice-id args)}] - (base58 (:ipfs-data args)))) - invoice-id (:invoice-id args) - job-story-id (:job-story/id ipfs-data) - invoice-message (base58 (:ipfs-data args)))) - job-id (:job args) - invoice-id (:invoice-id args) - job-story (base58 (:ipfs-data args)))) - ;; job-id (:job args) ; FIXME: after re-deploying the contracts can use this added event field to get the job contract address (instead of relying on IPFS) - job-id (:job/id ipfs-data) - invoice-id (:invoice-id args) - offered-value (offered-vec->flat-map (get-in args [:_value-for-invoicer 0])) - job-story (base58 (:ipfs-data args)))) - job-id (:job args) - job-story-message-type (:job-story-message/type ipfs-data) - message {:job-story/id (:job-story/id ipfs-data) - :job/id job-id - :candidate (:candidate ipfs-data) - :message/type :job-story-message - :job-story-message/type job-story-message-type - :message/text (:text ipfs-data) - :message/creator (:message/creator ipfs-data) - :message/date-created (get-timestamp)}] - (flat-map (first (:quote args))) - token-type (enum-val->token-type (:token-type quoted-value)) - for-the-db {:job/id (:job args) - :user/id (:arbiter args) - :job-arbiter/fee (:token-amount quoted-value) - :job-arbiter/fee-currency-id (if (keyword? token-type) - (name token-type) - (str token-type)) - :job-arbiter/status "quote-set"}] - (>> Handling event quote-for-arbitration-accepted" args)) - (let [arbiter-id (:arbiter args) - job-id (:job args) - new-accepted-arbiter {:job/id job-id - :user/id arbiter-id - :job-arbiter/date-accepted (get-timestamp) - :job-arbiter/status "accepted"} - previous-accepted-query {:select [:JobArbiter.job/id :JobArbiter.user/id] - :from [:JobArbiter] - :where [:and [:ilike :JobArbiter.job/id job-id] - [:= :JobArbiter.job-arbiter/status "accepted"]]} - previous-accepted-arbiter (>> Handling event ArbitersInvited" args)) - (let [job-id (:job args) - arbiters (:arbiters args)] - (doseq [arbiter arbiters] - ;; Guard against error of adding same arbitrer more than once (can be invited multiple times) - (if (not (:exists (>> handle-arbiters-invited Avoided adding duplicate" {:job job-id :arbiter arbiter})))))) - - -(defn handle-job-ended - [conn _ {:keys [args]}] - (safe-go - (log/info (str "Handling event job-ended" args)) - (let [job-id (:job args) - job-status "ended" - stories (flat-map funds) - job-id (:job args) - funding-base {:tx (:transaction-hash event) - :job/id job-id - :job-funding/created-at (get-timestamp)} - extract-token-info (fn [funds] - [(-> funds :token-type enum-val->token-type) - (:token-address funds)]) - tokens-info (map extract-token-info funds-map) - funding-updates (map (fn [tv] - (merge - funding-base - {:job-funding/amount (movement-sign-fn (:token-amount tv)) - :token-detail/id (:token-address tv)})) - funds-map)] - (doseq [[token-type token-address] tokens-info] (ensure-db-token-details token-type token-address conn)) - (doseq [funding funding-updates] - (t-api/add-event! span "funding-details" funding) - (t-api/start-active-span - "add-funding-to-db" - (fn [span] - (go! - (>> HANDLE TEST EVENT args: " args)) - - ;; ;; Syncer Start ;; ;; @@ -367,11 +52,11 @@ {} web3-events-map)] (fn [err {:keys [:block-number] :as event}] - (safe-go! + (async/go (let [contract-key (-> event :contract :contract-key) event-key (-> event :event) handler (get contract-ev->handler [contract-key event-key]) - span (t-api/start-span (str (name contract-key) "." (name event-key))) + span (t-api/start-span (str (name (or contract-key "UnnamedContract")) "." (name (or event-key "UnnamedEvent")))) conn (flat-map + enum-val->token-type]] + [ethlance.shared.token-utils :as token-utils] + [ethlance.shared.utils :as shared-utils] + [honeysql.core :as sql] + [taoensso.timbre :as log])) + + +(defn get-timestamp + ([] (get-timestamp {})) + ([_event] (.now js/Date))) + + +(defn build-ethlance-job-data-from-ipfs-object + [ethlance-job-data] + {:job/title (:job/title ethlance-job-data) + :job/description (:job/description ethlance-job-data) + :job/category (:job/category ethlance-job-data) + :job/required-skills (:job/required-skills ethlance-job-data) + :job/required-experience-level (:job/required-experience-level ethlance-job-data) + :job/language-id nil; TODO: where does it come from + :job/bid-option (:job/bid-option ethlance-job-data) + :job/estimated-project-length (:job/estimated-project-length ethlance-job-data) + :job/invitation-only? nil ; TODO: where does it come from + :job/required-availability (:job/required-availability ethlance-job-data)}) + + +(defn ensure-db-token-details + [token-type token-address conn] + (go + (let [eth-token-details {:address "0x0000000000000000000000000000000000000000" + :name "Ether" + :symbol "ETH" + :type :eth + :decimals 18}] + (when (not (>> Handling event job-created: " args) + (let [ipfs-hash (shared-utils/hex->base58 (:ipfs-data args)) + ipfs-job-content (flat-map (first (:offered-values args))) + token-address (:token-address offered-value) + token-type (enum-val->token-type (:token-type offered-value)) + token-amount (:token-amount offered-value) + for-the-db (merge {:job/id (:job args) + :job/status "active" ; draft -> active -> finished hiring -> closed + :job/creator (:creator args) + :job/date-created (get-timestamp event) + :job/date-updated (get-timestamp event) + + :job/token-type token-type + :job/token-amount token-amount + :job/token-address token-address + :job/token-id (:token-id offered-value) + :invited-arbiters (get args :invited-arbiters [])} + (build-ethlance-job-data-from-ipfs-object ipfs-job-content))] + (log/debug ">>> handle-job-created" for-the-db) + (base58 (:ipfs-data args)))) + job-story-id (:job-story/id ipfs-data) + invoicer (:invoicer args) + offered-value (offered-vec->flat-map (first (:invoiced-value args))) + invoice-message {:job-story/id job-story-id + :message/type :job-story-message + :job-story-message/type :invoice + :message/text (:message/text ipfs-data) + :message/creator invoicer + :message/date-created (get-timestamp) + :invoice/date-requested (get-timestamp) + :invoice/status "created" + :invoice/amount-requested (:token-amount offered-value) + :invoice/hours-worked (:invoice/hours-worked ipfs-data) + :invoice/hourly-rate (:invoice/hourly-rate ipfs-data) + :invoice/ref-id (:invoice-id args)}] + (base58 (:ipfs-data args)))) + invoice-id (:invoice-id args) + job-story-id (:job-story/id ipfs-data) + invoice-message (base58 (:ipfs-data args)))) + job-id (:job args) + invoice-id (:invoice-id args) + job-story (base58 (:ipfs-data args)))) + ;; job-id (:job args) ; FIXME: after re-deploying the contracts can use this added event field to get the job contract address (instead of relying on IPFS) + job-id (:job/id ipfs-data) + invoice-id (:invoice-id args) + offered-value (offered-vec->flat-map (get-in args [:_value-for-invoicer 0])) + job-story (base58 (:ipfs-data args)))) + job-id (:job args) + job-story-message-type (:job-story-message/type ipfs-data) + message {:job-story/id (:job-story/id ipfs-data) + :job/id job-id + :candidate (:candidate ipfs-data) + :message/type :job-story-message + :job-story-message/type job-story-message-type + :message/text (:text ipfs-data) + :message/creator (:message/creator ipfs-data) + :message/date-created (get-timestamp)}] + (flat-map (first (:quote args))) + token-type (enum-val->token-type (:token-type quoted-value)) + for-the-db {:job/id (:job args) + :user/id (:arbiter args) + :job-arbiter/fee (:token-amount quoted-value) + :job-arbiter/fee-currency-id (if (keyword? token-type) + (name token-type) + (str token-type)) + :job-arbiter/status "quote-set"}] + (>> Handling event quote-for-arbitration-accepted" args)) + (let [arbiter-id (:arbiter args) + job-id (:job args) + new-accepted-arbiter {:job/id job-id + :user/id arbiter-id + :job-arbiter/date-accepted (get-timestamp) + :job-arbiter/status "accepted"} + previous-accepted-query {:select [:JobArbiter.job/id :JobArbiter.user/id] + :from [:JobArbiter] + :where [:and [:ilike :JobArbiter.job/id job-id] + [:= :JobArbiter.job-arbiter/status "accepted"]]} + previous-accepted-arbiter (>> Handling event ArbitersInvited" args)) + (let [job-id (:job args) + arbiters (:arbiters args)] + (doseq [arbiter arbiters] + ;; Guard against error of adding same arbitrer more than once (can be invited multiple times) + (if (not (:exists (>> handle-arbiters-invited Avoided adding duplicate" {:job job-id :arbiter arbiter})))))) + + +(defn handle-job-ended + [conn _ {:keys [args]}] + (safe-go + (log/info (str "Handling event job-ended" args)) + (let [job-id (:job args) + job-status "ended" + stories (flat-map funds) + job-id (:job args) + funding-base {:tx (:transaction-hash event) + :job/id job-id + :job-funding/created-at (get-timestamp)} + extract-token-info (fn [funds] + [(-> funds :token-type enum-val->token-type) + (:token-address funds)]) + tokens-info (map extract-token-info funds-map) + funding-updates (map (fn [tv] + (merge + funding-base + {:job-funding/amount (movement-sign-fn (:token-amount tv)) + :token-detail/id (:token-address tv)})) + funds-map)] + (doseq [[token-type token-address] tokens-info] (ensure-db-token-details token-type token-address conn)) + (doseq [funding funding-updates] + (>> 1 of 3: IPFS get-ipfs-meta " meta-hash)) (js/Promise. (fn [resolve reject] - (log/info (str "Downloading: " "/ipfs/" meta-hash) ::get-ipfs-meta) + (log/info (str "2 of 3: Downloading: " "/ipfs/" meta-hash) ::get-ipfs-meta) (ipfs-files/fget (str "/ipfs/" meta-hash) {:req-opts {:compress false}} (fn [err content] + (log/info (str "3 of 3: ethlance.server.utils/get-ipfs-meta IPFS callback" {:err err :content content})) (cond err (let [err-txt "Error when retrieving metadata from ipfs"] @@ -46,6 +48,7 @@ :connection conn :error err}) ::get-ipfs-meta) + (println ">>> get-ipfs-meta REJECT") (reject (str err-txt " : " err))) (empty? content) diff --git a/server/src/tests/new_syncer_test.cljs b/server/src/tests/new_syncer_test.cljs new file mode 100644 index 00000000..68945052 --- /dev/null +++ b/server/src/tests/new_syncer_test.cljs @@ -0,0 +1,61 @@ +(ns tests.new-syncer-test + (:require + [cljs.test :refer-macros [deftest is async testing]] + [clojure.core.async :as async :refer [! go]:include-macros true] + [ethlance.server.new-syncer.core :as new-syncer.core] + )) + +(deftest test-init-syncer-single + (testing "processing one by one" + (async done + (go + (let [source (async/chan) + context (fn [handler] (handler "I am DB")) + events-processed (atom []) + add-to-processed (fn [_conn _err event] (swap! events-processed conj event)) + async-handler (fn [_conn _err event] (go (add-to-processed _conn _err event))) + handlers {:JobCreated add-to-processed + :FundsAdded async-handler} + syncer (new-syncer.core/init-syncer source handlers context) + ev-job-created {:event :JobCreated} + ev-funds-added {:event :FundsAdded}] + (>! source [nil ev-job-created]) + (! source [nil ev-funds-added]) + (! source [nil ev-job-created]) + (>! source [nil ev-funds-added]) + (loop [] + (when (>> 2nd test @events-processed" @events-processed) + + (done)))))) + +; (deftest test-process-past-events) + +; (deftest test-process-new-events +; (async done +; (let []))) diff --git a/server/yarn.lock b/server/yarn.lock index 95b4a8b7..d03849c5 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -82,6 +82,18 @@ core-js-pure "^3.25.1" regenerator-runtime "^0.13.11" +"@chainsafe/is-ip@^2.0.1", "@chainsafe/is-ip@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/is-ip/-/is-ip-2.0.2.tgz#7311e7403f11d8c5cfa48111f56fcecaac37c9f6" + integrity sha512-ndGqEMG1W5WkGagaqOZHpPU172AGdxr+LD15sv3WIUvT5oCFUrG1Y0CW/v2Egwj4JXEvSibaIIIqImsm98y1nA== + +"@chainsafe/netmask@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@chainsafe/netmask/-/netmask-2.0.0.tgz#0d4a75f47919f65011da4327a3845c9661f1038a" + integrity sha512-I3Z+6SWUoaljh3TBzCnCxjlUyN8tA+NAk5L6m9IxvCf1BENQTePzPMis97CoN/iMW1St3WN+AWCCRp+TTBRiDg== + dependencies: + "@chainsafe/is-ip" "^2.0.1" + "@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.4": version "2.6.5" resolved "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz" @@ -293,6 +305,246 @@ protobufjs "^7.2.4" yargs "^17.7.2" +"@helia/bitswap@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@helia/bitswap/-/bitswap-1.1.3.tgz#36ae3fff25551e9831a209205ca9ee304837b906" + integrity sha512-nCszNky/kOxaj1CZrZbzzFz6Fn7uNWigudn4KaLV+ZuFx6xyB8+t6aCmjKQ59me0WA3mwkmHkPtUOi9Y75zLSw== + dependencies: + "@helia/interface" "^4.3.1" + "@helia/utils" "^0.3.3" + "@libp2p/interface" "^1.1.2" + "@libp2p/logger" "^4.0.5" + "@libp2p/peer-collections" "^5.1.6" + "@libp2p/utils" "^5.2.3" + "@multiformats/multiaddr" "^12.1.14" + any-signal "^4.1.1" + interface-blockstore "^5.2.9" + interface-store "^5.1.7" + it-drain "^3.0.5" + it-length-prefixed "^9.0.0" + it-length-prefixed-stream "^1.1.6" + it-map "^3.0.5" + it-pipe "^3.0.1" + it-take "^3.0.1" + multiformats "^13.0.1" + p-defer "^4.0.0" + progress-events "^1.0.0" + protons-runtime "^5.0.0" + race-event "^1.2.0" + uint8-varint "^2.0.3" + uint8arraylist "^2.4.3" + uint8arrays "^5.0.1" + +"@helia/block-brokers@^3.0.1", "@helia/block-brokers@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@helia/block-brokers/-/block-brokers-3.0.3.tgz#4a83cf17ef2e06846b84a88a558f9211fff4a0b9" + integrity sha512-xSnmWv1jgeBJURcdF/KFOHEa1CQygk3jm1qxYPYqnMWxRXhsFG5Qi13EA+QfslCXyywfxbr4yJWleUUV2Mw4oQ== + dependencies: + "@helia/bitswap" "^1.1.3" + "@helia/interface" "^4.3.1" + "@helia/utils" "^0.3.3" + "@libp2p/interface" "^1.1.4" + "@libp2p/utils" "^5.2.6" + "@multiformats/multiaddr" "^12.2.1" + "@multiformats/multiaddr-matcher" "^1.2.0" + "@multiformats/multiaddr-to-uri" "^10.0.1" + interface-blockstore "^5.2.10" + interface-store "^5.1.8" + multiformats "^13.1.0" + progress-events "^1.0.0" + +"@helia/car@^3.1.5": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@helia/car/-/car-3.2.0.tgz#d2d574e4ca6577ffc355c6fce46eb0841db8541b" + integrity sha512-cSWlXoVCNGN8+ih52Or5MrQFKRnv7EzuhDFAkHLCzFPPf6j7iPn2JO2z+1HXU2nZSbanDhMJm0L7wTk9MeNaGQ== + dependencies: + "@helia/interface" "^4.3.1" + "@ipld/car" "^5.3.0" + "@libp2p/interfaces" "^3.3.2" + "@libp2p/utils" "^5.4.6" + interface-blockstore "^5.2.10" + it-drain "^3.0.5" + it-map "^3.0.5" + multiformats "^13.1.0" + p-defer "^4.0.0" + p-queue "^8.0.1" + progress-events "^1.0.0" + +"@helia/delegated-routing-v1-http-api-client@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@helia/delegated-routing-v1-http-api-client/-/delegated-routing-v1-http-api-client-3.0.1.tgz#284d21a99a8b80707ded3aa2f38ee89ec7895176" + integrity sha512-Gkaw3B8IjgCCXtasa17j8wQaFdzph2s0RiLyrJTS2htmwVFWZEjLNLUDJeWsMHBoLBza8SrVGvQ9fiN3XD3rfg== + dependencies: + "@libp2p/interface" "^1.1.1" + "@libp2p/logger" "^4.0.4" + "@libp2p/peer-id" "^4.0.4" + "@multiformats/multiaddr" "^12.1.3" + any-signal "^4.1.1" + browser-readablestream-to-it "^2.0.3" + ipns "^9.0.0" + it-first "^3.0.3" + it-map "^3.0.4" + it-ndjson "^1.0.4" + multiformats "^13.0.0" + p-defer "^4.0.0" + p-queue "^8.0.1" + uint8arrays "^5.0.1" + +"@helia/http@^1.0.8": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@helia/http/-/http-1.0.10.tgz#0bb3039cb4a2b79aff803adc1799fd04a43e6497" + integrity sha512-W1+MyelS4+1Elv+eWdnBfPAybMYwFzXbqSd0aboa15HfUuRMcPsmirqaR5oqWd8K697ugtsS2b5wTH2e7Oyk/Q== + dependencies: + "@helia/block-brokers" "^3.0.3" + "@helia/interface" "^4.3.1" + "@helia/routers" "^1.1.1" + "@helia/utils" "^0.3.3" + blockstore-core "^4.4.0" + datastore-core "^9.2.9" + +"@helia/interface@^4.3.0", "@helia/interface@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@helia/interface/-/interface-4.3.1.tgz#064ad5a82a3d109c94e16a7a62ccb7faa07ca05b" + integrity sha512-jvuUUAQbLMhvMt+Lon7mJfJt5xJWiwn8aXtI9fHBpMNMsrKJOtefxAzwSr18xe+C9bMdOyRtocj2eFhs74bQ8w== + dependencies: + "@libp2p/interface" "^1.1.4" + "@multiformats/dns" "^1.0.1" + interface-blockstore "^5.2.10" + interface-datastore "^8.2.11" + interface-store "^5.1.8" + multiformats "^13.1.0" + progress-events "^1.0.0" + +"@helia/ipns@^7.2.2": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@helia/ipns/-/ipns-7.2.3.tgz#5b1f01af27706492e0f5c11098cbe2db0cfea437" + integrity sha512-xF9GM40aOfc/5Y6iqgOxAx5PjdW3qNfrlyYP1TcbRL7sR8bnOJjzCiZxjMxVYCLALg3j3LZYl/2foqjtddV/eg== + dependencies: + "@helia/interface" "^4.3.1" + "@libp2p/interface" "^1.1.4" + "@libp2p/kad-dht" "^12.0.8" + "@libp2p/logger" "^4.0.7" + "@libp2p/peer-id" "^4.0.7" + "@multiformats/dns" "^1.0.1" + interface-datastore "^8.2.11" + ipns "^9.1.0" + multiformats "^13.1.0" + progress-events "^1.0.0" + uint8arrays "^5.0.2" + +"@helia/routers@^1.1.0", "@helia/routers@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@helia/routers/-/routers-1.1.1.tgz#fa60ea61ebb02c28eec513a894a3757fccd568a5" + integrity sha512-LsEkUAno4PiQ1cmwxFnYWy5xQicpzjXyYeRJEGLjAnAXin8hq0JPkEouZx8vTlmSf1Rde4RSaTu3+3H1qj5ccw== + dependencies: + "@helia/delegated-routing-v1-http-api-client" "^3.0.0" + "@helia/interface" "^4.3.1" + "@libp2p/interface" "^1.1.4" + "@multiformats/uri-to-multiaddr" "^8.0.0" + ipns "^9.0.0" + it-first "^3.0.4" + it-map "^3.0.5" + multiformats "^13.1.0" + uint8arrays "^5.0.2" + +"@helia/utils@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@helia/utils/-/utils-0.3.3.tgz#0e6522ba14f4db905d038ac4c3743a5bc5236560" + integrity sha512-iCS8dJRULgltfx7aLLoqfjWUpqBWrTyouCToB9RgHpNs4lHcIsZn/VSbHyjC4NUF9nIWsxhH/3UAdvWl23HEgw== + dependencies: + "@helia/interface" "^4.3.1" + "@ipld/dag-cbor" "^9.2.0" + "@ipld/dag-json" "^10.2.0" + "@ipld/dag-pb" "^4.1.0" + "@libp2p/crypto" "^4.0.6" + "@libp2p/interface" "^1.1.4" + "@libp2p/logger" "^4.0.7" + "@libp2p/utils" "^5.2.6" + "@multiformats/dns" "^1.0.1" + "@types/murmurhash3js-revisited" "^3.0.3" + any-signal "^4.1.1" + blockstore-core "^4.4.1" + cborg "^4.0.9" + interface-blockstore "^5.2.10" + interface-datastore "^8.2.11" + interface-store "^5.1.8" + it-drain "^3.0.5" + it-filter "^3.0.4" + it-foreach "^2.0.6" + it-merge "^3.0.3" + mortice "^3.0.4" + multiformats "^13.1.0" + murmurhash3js-revisited "^3.0.0" + p-defer "^4.0.1" + progress-events "^1.0.0" + uint8arraylist "^2.4.8" + uint8arrays "^5.0.2" + +"@helia/verified-fetch@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@helia/verified-fetch/-/verified-fetch-1.5.0.tgz#4b9d75f039117b2677aa000321b10662b940bcb8" + integrity sha512-30gi2r/u55zA6DBk4mY4RAIx6NQqrSPEUKdN9QUBNFqbotIAQ6+CBV8/scG0NF2eV/WL5XnIRn2YL8IZagMG2g== + dependencies: + "@helia/block-brokers" "^3.0.1" + "@helia/car" "^3.1.5" + "@helia/http" "^1.0.8" + "@helia/interface" "^4.3.0" + "@helia/ipns" "^7.2.2" + "@helia/routers" "^1.1.0" + "@ipld/dag-cbor" "^9.2.0" + "@ipld/dag-json" "^10.2.0" + "@ipld/dag-pb" "^4.1.0" + "@libp2p/interface" "^1.4.0" + "@libp2p/kad-dht" "^12.0.17" + "@libp2p/peer-id" "^4.1.2" + "@multiformats/dns" "^1.0.6" + cborg "^4.2.0" + hashlru "^2.3.0" + interface-blockstore "^5.2.10" + interface-datastore "^8.2.11" + ipfs-unixfs-exporter "^13.5.0" + it-map "^3.1.0" + it-pipe "^3.0.1" + it-tar "^6.0.5" + it-to-browser-readablestream "^2.0.9" + lru-cache "^10.2.2" + multiformats "^13.1.0" + progress-events "^1.0.0" + uint8arrays "^5.1.0" + +"@ipld/car@^5.3.0": + version "5.3.2" + resolved "https://registry.yarnpkg.com/@ipld/car/-/car-5.3.2.tgz#b6f9b5e30e0de5d45aff4494e8c3e2667ce9e0a4" + integrity sha512-Bb4XrCFlnsCb9tTzZ1I8zo9O61D9qm7HfvuYrQ9gzdE8YhjyVIjrjmHmnoSWV/uCmyc2/bcqiDPIg+9WljXNzg== + dependencies: + "@ipld/dag-cbor" "^9.0.7" + cborg "^4.0.5" + multiformats "^13.0.0" + varint "^6.0.0" + +"@ipld/dag-cbor@^9.0.0", "@ipld/dag-cbor@^9.0.7", "@ipld/dag-cbor@^9.2.0": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@ipld/dag-cbor/-/dag-cbor-9.2.1.tgz#e61f413770bb0fb27ffafa9577049869272d2056" + integrity sha512-nyY48yE7r3dnJVlxrdaimrbloh4RokQaNRdI//btfTkcTEZbpmSrbYcBQ4VKTf8ZxXAOUJy4VsRpkJo+y9RTnA== + dependencies: + cborg "^4.0.0" + multiformats "^13.1.0" + +"@ipld/dag-json@^10.1.7", "@ipld/dag-json@^10.2.0": + version "10.2.2" + resolved "https://registry.yarnpkg.com/@ipld/dag-json/-/dag-json-10.2.2.tgz#85f498abf4432df9296ace2e40de95e5e1e2d38d" + integrity sha512-NnU8HdHKwAoGyrW3S09NMa8aZw0tImLRyR64hoafpLpDpAbA9g1+fb24JsdlugbL4sXUQVwDVA+qK4Ud8V83lA== + dependencies: + cborg "^4.0.0" + multiformats "^13.1.0" + +"@ipld/dag-pb@^4.0.0", "@ipld/dag-pb@^4.1.0": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@ipld/dag-pb/-/dag-pb-4.1.2.tgz#39db25311aeb2745ec20bfc745d91a577832b6ac" + integrity sha512-BSztO4l3C+ya9HjCaQot26Y4AVsqIKtnn6+23ubc1usucnf6yoTBme18oCCdM6gKBMxuPqju5ye3lh9WEJsdeQ== + dependencies: + multiformats "^13.1.0" + "@josephg/resolvable@^1.0.0": version "1.0.1" resolved "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz" @@ -303,16 +555,234 @@ resolved "https://registry.yarnpkg.com/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz#9299f82874bab9e4c7f9c48d865becbfe8d6907c" integrity sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw== +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" + integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== + +"@libp2p/crypto@^4.0.0", "@libp2p/crypto@^4.0.6", "@libp2p/crypto@^4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@libp2p/crypto/-/crypto-4.1.8.tgz#f8b10b3aa53403b5cfc00cc04aa8548807a03e0c" + integrity sha512-j8d1gOS6ypt6CSYgBTJKSTGsht3SFPkhfOkGND6sUCl1w9pRslDlvFnU9UrNHLMiaNmVHaeS9B2IKzKMbLX92Q== + dependencies: + "@libp2p/interface" "^1.6.3" + "@noble/curves" "^1.4.0" + "@noble/hashes" "^1.4.0" + asn1js "^3.0.5" + multiformats "^13.1.0" + protons-runtime "^5.4.0" + uint8arraylist "^2.4.8" + uint8arrays "^5.1.0" + +"@libp2p/interface-internal@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@libp2p/interface-internal/-/interface-internal-1.3.3.tgz#29f7f9e183461c03defd3511d131dbf37190b554" + integrity sha512-xng1cBGDhSZmCu0kUEv3363oSgpoPmvpDr11wumhKNEgGOwBVbEr0v7serYcrlORxFmyUBW8y98CkPRJxskPLA== + dependencies: + "@libp2p/interface" "^1.6.3" + "@libp2p/peer-collections" "^5.2.8" + "@multiformats/multiaddr" "^12.2.3" + progress-events "^1.0.0" + uint8arraylist "^2.4.8" + +"@libp2p/interface@^1.0.0", "@libp2p/interface@^1.1.0", "@libp2p/interface@^1.1.1", "@libp2p/interface@^1.1.2", "@libp2p/interface@^1.1.4", "@libp2p/interface@^1.4.0", "@libp2p/interface@^1.6.3": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@libp2p/interface/-/interface-1.6.3.tgz#3673e05d5bfc139e4fc81d8ce44468ce9a98ffc4" + integrity sha512-Tm8W5Q2FsjcSdeA5BvP/GTUq/lp3SjeW6GPmWbbIasBJdv67UGHahu8YDFTME90IxTijnikkfGNkOPsd/4UuvA== + dependencies: + "@multiformats/multiaddr" "^12.2.3" + it-pushable "^3.2.3" + it-stream-types "^2.0.1" + multiformats "^13.1.0" + progress-events "^1.0.0" + uint8arraylist "^2.4.8" + +"@libp2p/interfaces@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@libp2p/interfaces/-/interfaces-3.3.2.tgz#5d8079be845b0960939b5b18880e785a4714465a" + integrity sha512-p/M7plbrxLzuQchvNwww1Was7ZeGE2NaOFulMaZBYIihU8z3fhaV+a033OqnC/0NTX/yhfdNOG7znhYq3XoR/g== + +"@libp2p/kad-dht@^12.0.17", "@libp2p/kad-dht@^12.0.8": + version "12.1.4" + resolved "https://registry.yarnpkg.com/@libp2p/kad-dht/-/kad-dht-12.1.4.tgz#7935ec13894095fc2fbe87ed43f88b1b1a7b884c" + integrity sha512-TWg3WB/Ghqz2vVOBxZz3PD0gDw1j24GlcQiJw5AieXMY1va8ZxkYyJtpHluhPpjLnlI4zxNLbE30A05Tp6XD4w== + dependencies: + "@libp2p/crypto" "^4.1.8" + "@libp2p/interface" "^1.6.3" + "@libp2p/interface-internal" "^1.3.3" + "@libp2p/peer-collections" "^5.2.8" + "@libp2p/peer-id" "^4.2.3" + "@libp2p/record" "^4.0.4" + "@libp2p/utils" "^5.4.8" + "@multiformats/multiaddr" "^12.2.3" + any-signal "^4.1.1" + hashlru "^2.3.0" + interface-datastore "^8.2.11" + it-drain "^3.0.7" + it-length "^3.0.6" + it-length-prefixed "^9.0.4" + it-map "^3.1.0" + it-merge "^3.0.5" + it-parallel "^3.0.7" + it-pipe "^3.0.1" + it-protobuf-stream "^1.1.3" + it-take "^3.0.5" + multiformats "^13.1.0" + p-defer "^4.0.1" + p-event "^6.0.1" + p-queue "^8.0.1" + progress-events "^1.0.0" + protons-runtime "^5.4.0" + race-signal "^1.0.2" + uint8-varint "^2.0.4" + uint8arraylist "^2.4.8" + uint8arrays "^5.1.0" + +"@libp2p/logger@^4.0.19", "@libp2p/logger@^4.0.3", "@libp2p/logger@^4.0.4", "@libp2p/logger@^4.0.5", "@libp2p/logger@^4.0.6", "@libp2p/logger@^4.0.7": + version "4.0.19" + resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-4.0.19.tgz#055364d719d3db2e45764ce04b4644e047a29c3b" + integrity sha512-VKpIMbjzs60AaTezh55iEDPJ0W2icbkJkBXSlAMycCT4C+RYxOTRgevasw3mDB6+Lj9etM0nfa4vutoG4fsYCw== + dependencies: + "@libp2p/interface" "^1.6.3" + "@multiformats/multiaddr" "^12.2.3" + interface-datastore "^8.2.11" + multiformats "^13.1.0" + weald "^1.0.2" + +"@libp2p/peer-collections@^5.1.6", "@libp2p/peer-collections@^5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@libp2p/peer-collections/-/peer-collections-5.2.8.tgz#63910791fed3c2eee2f56554a6662bbd04c93e99" + integrity sha512-dIakIFms3GgFYg4lVgl9afAm+OAxGTofz4KdFnVrlNW1z6VFhTbnRtvTweR6woSr2es1+Fu6WutmZ+62Fn0iOQ== + dependencies: + "@libp2p/interface" "^1.6.3" + "@libp2p/peer-id" "^4.2.3" + "@libp2p/utils" "^5.4.8" + +"@libp2p/peer-id@^4.0.3", "@libp2p/peer-id@^4.0.4", "@libp2p/peer-id@^4.0.7", "@libp2p/peer-id@^4.1.2", "@libp2p/peer-id@^4.2.3": + version "4.2.3" + resolved "https://registry.yarnpkg.com/@libp2p/peer-id/-/peer-id-4.2.3.tgz#21c2e8c265db70fe63670c60ed760316dde4dd64" + integrity sha512-hRqPzcYOz/5q6QvHYdmPMGeFZCjC/9qxQ/+jstSDMnY1DuKEXCre2+tCpG9OeRAFyPBbs5isfaqbY3zNZV2pqA== + dependencies: + "@libp2p/interface" "^1.6.3" + multiformats "^13.1.0" + uint8arrays "^5.1.0" + +"@libp2p/record@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@libp2p/record/-/record-4.0.4.tgz#9300e5a10ebc543f1d8df0b95a7181d633f039f1" + integrity sha512-wEEeHXGNIcc8HtGbgGMuSHbboUWMxKG7OxALFwkE+KACgfRJZTESOp6XIdZnyC0r9lfEFsjF01pFKBTzoBmWEQ== + dependencies: + protons-runtime "^5.4.0" + uint8arraylist "^2.4.8" + uint8arrays "^5.1.0" + +"@libp2p/utils@^5.2.3", "@libp2p/utils@^5.2.6", "@libp2p/utils@^5.4.6", "@libp2p/utils@^5.4.8": + version "5.4.8" + resolved "https://registry.yarnpkg.com/@libp2p/utils/-/utils-5.4.8.tgz#f424b953fd74657a6ec5c061f68daac9489be361" + integrity sha512-3ysAjrheDvcrUd8RWOCwa6Hm+5FMsYOlPq9IPllfD0jOyHO2RHc/huvAmjBg/PWrTdUyx1nWQf9wmdQFgTDUDQ== + dependencies: + "@chainsafe/is-ip" "^2.0.2" + "@libp2p/crypto" "^4.1.8" + "@libp2p/interface" "^1.6.3" + "@libp2p/logger" "^4.0.19" + "@multiformats/multiaddr" "^12.2.3" + "@multiformats/multiaddr-matcher" "^1.2.1" + "@sindresorhus/fnv1a" "^3.1.0" + "@types/murmurhash3js-revisited" "^3.0.3" + any-signal "^4.1.1" + delay "^6.0.0" + get-iterator "^2.0.1" + is-loopback-addr "^2.0.2" + it-pushable "^3.2.3" + it-stream-types "^2.0.1" + murmurhash3js-revisited "^3.0.0" + netmask "^2.0.2" + p-defer "^4.0.1" + race-event "^1.3.0" + race-signal "^1.0.2" + uint8arraylist "^2.4.8" + uint8arrays "^5.1.0" + "@multiformats/base-x@^4.0.1": version "4.0.1" resolved "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz" integrity sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw== +"@multiformats/dns@^1.0.1", "@multiformats/dns@^1.0.3", "@multiformats/dns@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@multiformats/dns/-/dns-1.0.6.tgz#b8c7de11459a02a5f4e609d35d3cdb95cb6ad152" + integrity sha512-nt/5UqjMPtyvkG9BQYdJ4GfLK3nMqGpFZOzf4hAmIa0sJh2LlS9YKXZ4FgwBDsaHvzZqR/rUFIywIc7pkHNNuw== + dependencies: + "@types/dns-packet" "^5.6.5" + buffer "^6.0.3" + dns-packet "^5.6.1" + hashlru "^2.3.0" + p-queue "^8.0.1" + progress-events "^1.0.0" + uint8arrays "^5.0.2" + +"@multiformats/multiaddr-matcher@^1.2.0", "@multiformats/multiaddr-matcher@^1.2.1": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@multiformats/multiaddr-matcher/-/multiaddr-matcher-1.2.4.tgz#affb3c63b5cd83b44156be19583981651373ec2e" + integrity sha512-GgpqzQFL4Mj8t7cLNHC5nuYUuSm0kTtSUyYswiyWwTSUY3XwRAMx0UiFWQg+ETk0u+/IvFaHxfnyEoH3tasvwg== + dependencies: + "@chainsafe/is-ip" "^2.0.1" + "@multiformats/multiaddr" "^12.0.0" + multiformats "^13.0.0" + +"@multiformats/multiaddr-to-uri@^10.0.1": + version "10.1.0" + resolved "https://registry.yarnpkg.com/@multiformats/multiaddr-to-uri/-/multiaddr-to-uri-10.1.0.tgz#f52312cee11b6ad25997e743d9c575c44726c7d0" + integrity sha512-ZNwSAx3ssBWwd4y0LKrOsq9xG7LBHboQxnUdSduNc2fTh/NS1UjA2slgUy6KHxH5k9S2DSus0iU2CoyJyN0/pg== + dependencies: + "@multiformats/multiaddr" "^12.3.0" + +"@multiformats/multiaddr@^12.0.0", "@multiformats/multiaddr@^12.1.14", "@multiformats/multiaddr@^12.1.3", "@multiformats/multiaddr@^12.2.1", "@multiformats/multiaddr@^12.2.3", "@multiformats/multiaddr@^12.3.0": + version "12.3.0" + resolved "https://registry.yarnpkg.com/@multiformats/multiaddr/-/multiaddr-12.3.0.tgz#b1422813446e5cdec4b0f6cba51f93239f390884" + integrity sha512-JQ8Gc/jgucqqvEaDTFN/AvxlYDHEE7lgEWLMYW7hKZkWggER+GvG/tVxUgUxIP8M0vFpvEHKKHE0lKzyMsgi8Q== + dependencies: + "@chainsafe/is-ip" "^2.0.1" + "@chainsafe/netmask" "^2.0.0" + "@libp2p/interface" "^1.0.0" + "@multiformats/dns" "^1.0.3" + multiformats "^13.0.0" + uint8-varint "^2.0.1" + uint8arrays "^5.0.0" + +"@multiformats/murmur3@^2.0.0": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@multiformats/murmur3/-/murmur3-2.1.8.tgz#81c1c15b6391109f3febfca4b3205196615a04e9" + integrity sha512-6vId1C46ra3R1sbJUOFCZnsUIveR9oF20yhPmAFxPm0JfrX3/ZRCgP3YDrBzlGoEppOXnA9czHeYc0T9mB6hbA== + dependencies: + multiformats "^13.0.0" + murmurhash3js-revisited "^3.0.0" + +"@multiformats/uri-to-multiaddr@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@multiformats/uri-to-multiaddr/-/uri-to-multiaddr-8.0.0.tgz#cd4c3248c0039731504b69ae74ae732e954119f7" + integrity sha512-86O+gY6JTnCv0O/IxTKV+1+GACoEBTr5Cfyh+FdzStWneviz2AZwLK8Hsys5dbfMgT//Vs7FolMiEHURlCel8w== + dependencies: + "@multiformats/multiaddr" "^12.1.14" + is-ip "^5.0.0" + +"@noble/curves@^1.4.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.5.0.tgz#7a9b9b507065d516e6dce275a1e31db8d2a100dd" + integrity sha512-J5EKamIHnKPyClwVrzmaf5wSdQXgdHcPZIZLu3bwnbeCx8/7NPK5q2ZBWF+5FvYGByjiQQsJYX6jfgB2wDPn3A== + dependencies: + "@noble/hashes" "1.4.0" + "@noble/hashes@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== +"@noble/hashes@1.4.0", "@noble/hashes@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + "@noble/secp256k1@1.7.1": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" @@ -622,6 +1092,11 @@ "@sentry/types" "7.31.1" tslib "^1.9.3" +"@sindresorhus/fnv1a@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/fnv1a/-/fnv1a-3.1.0.tgz#f8e46597298f6fd4c12dc901cdd4e73beb4d24fa" + integrity sha512-KV321z5m/0nuAg83W1dPLy85HpHDk7Sdi4fJbwvacWsEhAh+rZUW4ZfGcXmUIvjZg4ss2bcwNlRhJ7GBEUG08w== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" @@ -722,6 +1197,13 @@ dependencies: "@types/node" "*" +"@types/dns-packet@^5.6.5": + version "5.6.5" + resolved "https://registry.yarnpkg.com/@types/dns-packet/-/dns-packet-5.6.5.tgz#49fc29a40f5d30227ed028fa1ee82601d3745e15" + integrity sha512-qXOC7XLOEe43ehtWJCMnQXvgcIpv6rPmQ1jXT98Ad8A3TB1Ue50jsCbSSSyuazScEuZ/Q026vHbrOTVkmwA+7Q== + dependencies: + "@types/node" "*" + "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.31": version "4.17.33" resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz" @@ -815,6 +1297,11 @@ resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz" integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== +"@types/murmurhash3js-revisited@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.3.tgz#94e247168a18342477639126da8f01353437e8d0" + integrity sha512-QvlqvYtGBYIDeO8dFdY4djkRubcrc+yTJtBc7n8VZPlJDUS/00A+PssbvERM8f9bYRmcaSEHPZgZojeQj7kzAA== + "@types/node@*": version "18.11.18" resolved "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz" @@ -959,6 +1446,11 @@ ansi-styles@^4.0.0: dependencies: color-convert "^2.0.1" +any-signal@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/any-signal/-/any-signal-4.1.1.tgz#928416c355c66899e6b2a91cad4488f0324bae03" + integrity sha512-iADenERppdC+A2YKbOXXB2WUeABLaM6qnpZ70kZbPZ1cZMMJ7eF+3CaYm+/PhBizgkzlvssC7QuHS30oOiQYWA== + apollo-cache-control@^0.15.0: version "0.15.0" resolved "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.15.0.tgz" @@ -1172,6 +1664,15 @@ asn1@~0.2.3: dependencies: safer-buffer "~2.1.0" +asn1js@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.5.tgz#5ea36820443dbefb51cc7f88a2ebb5b462114f38" + integrity sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ== + dependencies: + pvtsutils "^1.3.2" + pvutils "^1.1.3" + tslib "^2.4.0" + assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" @@ -1289,6 +1790,21 @@ blakejs@^1.1.0: resolved "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz" integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== +blockstore-core@^4.4.0, blockstore-core@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/blockstore-core/-/blockstore-core-4.4.1.tgz#0804c8a00f096c43e1b679b1711a66157a421c5e" + integrity sha512-peXfL9ZLx1cb84QALocMjhT8CsQ4JsreI/AitlN1inipSdC/G+jcYVJCqeCD5ecSTv/0LMpg8NlAPH/eBYZLjA== + dependencies: + "@libp2p/logger" "^4.0.6" + err-code "^3.0.1" + interface-blockstore "^5.0.0" + interface-store "^5.0.0" + it-drain "^3.0.5" + it-filter "^3.0.4" + it-merge "^3.0.3" + it-pushable "^3.2.3" + multiformats "^13.0.1" + bluebird@^3.5.0: version "3.7.2" resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" @@ -1348,6 +1864,11 @@ brorand@^1.0.1, brorand@^1.1.0: resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== +browser-readablestream-to-it@^2.0.3: + version "2.0.7" + resolved "https://registry.yarnpkg.com/browser-readablestream-to-it/-/browser-readablestream-to-it-2.0.7.tgz#ddcc4b34a4b08ef415f89eb215297acea3e05fd0" + integrity sha512-g1Aznml3HmqTLSXylZhGwdfnAa67+vlNAYhT9ROJZkAxY7yYmWusND10olvCMPe4sVhZyVwn5tPkRzOg85kBEg== + browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz" @@ -1450,7 +1971,7 @@ buffer-xor@^1.0.3: resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz" integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== -buffer@6.0.3: +buffer@6.0.3, buffer@^6.0.3: version "6.0.3" resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -1548,6 +2069,11 @@ caseless@~0.12.0: resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== +cborg@^4.0.0, cborg@^4.0.1, cborg@^4.0.5, cborg@^4.0.9, cborg@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/cborg/-/cborg-4.2.3.tgz#0c16217022c085579edc5b204f693a261a12eb49" + integrity sha512-XBFbEJ6WMfn9L7woc2t+EzOxF8vGqddoopKBbrhIvZBt2WIUgSlT8xLmM6Aq1xv8eWt4yOSjwxWjYeuHU3CpJA== + chalk@2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz" @@ -1610,6 +2136,13 @@ cliui@^8.0.1: strip-ansi "^6.0.1" wrap-ansi "^7.0.0" +clone-regexp@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-3.0.0.tgz#c6dd5c6b85482306778f3dc4ac2bb967079069c2" + integrity sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw== + dependencies: + is-regexp "^3.0.0" + clone-response@^1.0.2: version "1.0.3" resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz" @@ -1696,6 +2229,11 @@ content-type@~1.0.4: resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +convert-hrtime@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/convert-hrtime/-/convert-hrtime-5.0.0.tgz#f2131236d4598b95de856926a67100a0a97e9fa3" + integrity sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" @@ -1825,6 +2363,24 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +datastore-core@^9.2.9: + version "9.2.9" + resolved "https://registry.yarnpkg.com/datastore-core/-/datastore-core-9.2.9.tgz#74b4dd53d4597b59038488ba5f92a7f81769f8df" + integrity sha512-wraWTPsbtdE7FFaVo3pwPuTB/zXsgwGGAm8BgBYwYAuzZCTS0MfXmd/HH1vR9s0/NFFjOVmBkGiWCvKxZ+QjVw== + dependencies: + "@libp2p/logger" "^4.0.6" + err-code "^3.0.1" + interface-datastore "^8.0.0" + interface-store "^5.0.0" + it-drain "^3.0.5" + it-filter "^3.0.4" + it-map "^3.0.5" + it-merge "^3.0.3" + it-pipe "^3.0.1" + it-pushable "^3.2.3" + it-sort "^3.0.4" + it-take "^3.0.4" + debug@2.6.9, debug@^2.2.0: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" @@ -1881,6 +2437,11 @@ define-properties@^1.1.3, define-properties@^1.1.4: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +delay@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-6.0.0.tgz#43749aefdf6cabd9e17b0d00bd3904525137e607" + integrity sha512-2NJozoOHQ4NuZuVIr5CWd0iiLVIRSDepakaovIN+9eIDHEhdCAEvSy2cuf1DCrPPQLvHmbqTHODlhHg8UCy4zw== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" @@ -1949,6 +2510,13 @@ dns-over-http-resolver@^1.0.0: native-fetch "^3.0.0" receptacle "^1.3.2" +dns-packet@^5.6.1: + version "5.6.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" + integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + dom-walk@^0.1.0: version "0.1.2" resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz" @@ -2026,6 +2594,11 @@ err-code@^2.0.3: resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== +err-code@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-3.0.1.tgz#a444c7b992705f2b120ee320b09972eef331c920" + integrity sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA== + es-abstract@^1.19.0, es-abstract@^1.20.4: version "1.21.1" resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz" @@ -2284,6 +2857,11 @@ eventemitter3@^3.1.0: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + events@^3.0.0: version "3.3.0" resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" @@ -2529,6 +3107,11 @@ function-bind@^1.1.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== +function-timeout@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/function-timeout/-/function-timeout-0.1.1.tgz#6bf71d3d24c894d43b2bec312cabb8c5add2e9da" + integrity sha512-0NVVC0TaP7dSTvn1yMiy6d6Q8gifzbvQafO46RtLG/kHJUBNd+pVRGOBoK44wNBvtSPUJRfdVvkFdD3p0xvyZg== + function.prototype.name@^1.1.5: version "1.1.5" resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" @@ -2558,6 +3141,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: has "^1.0.3" has-symbols "^1.0.3" +get-iterator@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-2.0.1.tgz#a904829f61bace789e0d64bd1a504c511a015c3f" + integrity sha512-7HuY/hebu4gryTDT7O/XY/fvY9wRByEGdK6QOa4of8npTcv0+NS6frFKABcf6S9EBAsveTuKTsZQQBFMMNILIg== + get-stream@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" @@ -2712,6 +3300,14 @@ graphql@14.2.1: dependencies: iterall "^1.2.2" +hamt-sharding@^3.0.0: + version "3.0.6" + resolved "https://registry.yarnpkg.com/hamt-sharding/-/hamt-sharding-3.0.6.tgz#3643107a3021af66ac95684aec87b196add5ba57" + integrity sha512-nZeamxfymIWLpVcAN0CRrb7uVq3hCOGj9IcL6NMA6VVCVWqj+h9Jo/SmaWuS92AEDf1thmHsM5D5c70hM3j2Tg== + dependencies: + sparse-array "^1.3.1" + uint8arrays "^5.0.1" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" @@ -2783,6 +3379,11 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hashlru@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/hashlru/-/hashlru-2.3.0.tgz#5dc15928b3f6961a2056416bb3a4910216fdfb51" + integrity sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A== + hasown@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" @@ -2932,6 +3533,32 @@ ini@~1.3.0: resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== +interface-blockstore@^5.0.0, interface-blockstore@^5.2.10, interface-blockstore@^5.2.9: + version "5.3.0" + resolved "https://registry.yarnpkg.com/interface-blockstore/-/interface-blockstore-5.3.0.tgz#1b22f415fcd3e59ef586a647bfd3eb01dc784bc1" + integrity sha512-MsOE2H9duZdpxXk7KVOQLaQnX4LfqHegshKxSr4b/YD44t13koT5Lg4lphZ0FwB5uvtvqQPm7LNcS0T/5Z2YUQ== + dependencies: + interface-store "6.0.0" + multiformats "^13.0.1" + +interface-datastore@^8.0.0, interface-datastore@^8.1.0, interface-datastore@^8.2.11: + version "8.3.0" + resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-8.3.0.tgz#0ce9a2f0f61f9fbe1c1734c6d10a0265193689f7" + integrity sha512-RM/rTSmRcnoCwGZIHrPm+nlGYVoT4R0lcFvNnDyhdFT4R6BuHHhfFP47UldVEjs98SfxLuMhaNMsyjI918saHw== + dependencies: + interface-store "6.0.0" + uint8arrays "^5.0.2" + +interface-store@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/interface-store/-/interface-store-6.0.0.tgz#8d8277a582f69d819134e125b686e147099a4728" + integrity sha512-HkjsDPsjA7SKkCr+TH1elUQApAAM3X3JPwrz3vFzaf614wI+ZD6GVvwKGZCHYcbSRqeZP/uzVPqezzeISeo5kA== + +interface-store@^5.0.0, interface-store@^5.1.7, interface-store@^5.1.8: + version "5.1.8" + resolved "https://registry.yarnpkg.com/interface-store/-/interface-store-5.1.8.tgz#94bf867d165b5c904cccf09adeba215a5b0f459e" + integrity sha512-7na81Uxkl0vqk0CBPO5PvyTkdaJBaezwUJGsMOz7riPOq0rJt+7W31iaopaMICWea/iykUsvNlPx/Tc+MxC3/w== + internal-slot@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz" @@ -2946,11 +3573,66 @@ ip-regex@^4.0.0: resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz" integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== +ip-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-5.0.0.tgz#cd313b2ae9c80c07bd3851e12bf4fa4dc5480632" + integrity sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +ipfs-unixfs-exporter@^13.5.0: + version "13.5.0" + resolved "https://registry.yarnpkg.com/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-13.5.0.tgz#48fafb272489cc2bf05757c16f3f44fa241ee038" + integrity sha512-s1eWXzoyhQFNEAB1p+QE3adjhW+lBdgpORmmjiCLiruHs5z7T5zsAgRVcWpM8LWYhq2flRtJHObb7Hg73J+oLQ== + dependencies: + "@ipld/dag-cbor" "^9.0.0" + "@ipld/dag-json" "^10.1.7" + "@ipld/dag-pb" "^4.0.0" + "@multiformats/murmur3" "^2.0.0" + err-code "^3.0.1" + hamt-sharding "^3.0.0" + interface-blockstore "^5.0.0" + ipfs-unixfs "^11.0.0" + it-filter "^3.0.2" + it-last "^3.0.2" + it-map "^3.0.3" + it-parallel "^3.0.0" + it-pipe "^3.0.1" + it-pushable "^3.1.0" + multiformats "^13.0.0" + p-queue "^8.0.1" + progress-events "^1.0.0" + +ipfs-unixfs@^11.0.0: + version "11.1.4" + resolved "https://registry.yarnpkg.com/ipfs-unixfs/-/ipfs-unixfs-11.1.4.tgz#392bfb819c1186cafff97794876bfdeb8c3a5bfe" + integrity sha512-RE4nyx5qgG2w7JOLj0Y0D7SfAR1ZkEdramNaBx0OSD4DlQ2Y2NORgc4FHfej3Pgy31v+QISDVP1pQJhdv3bUUg== + dependencies: + err-code "^3.0.1" + protons-runtime "^5.4.0" + uint8arraylist "^2.4.8" + +ipns@^9.0.0, ipns@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/ipns/-/ipns-9.1.0.tgz#de718378309f49b03f5eb6c5990c3db92ad38220" + integrity sha512-up2o1Qx9tSSfh73k69j3/Acacua6JbffTe5xA8+/fv6ibkQyhriMPHlgae1896DwmQkJrusKgBs7EAOi3yrO2w== + dependencies: + "@libp2p/crypto" "^4.0.0" + "@libp2p/interface" "^1.1.0" + "@libp2p/logger" "^4.0.3" + "@libp2p/peer-id" "^4.0.3" + cborg "^4.0.1" + err-code "^3.0.1" + interface-datastore "^8.1.0" + multiformats "^13.0.0" + protons-runtime "^5.2.1" + timestamp-nano "^1.0.0" + uint8arraylist "^2.4.8" + uint8arrays "^5.0.1" + is-arguments@^1.0.4: version "1.1.1" resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" @@ -3031,6 +3713,14 @@ is-ip@^3.1.0: dependencies: ip-regex "^4.0.0" +is-ip@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-5.0.1.tgz#bec44442c823e591aa6f4d6fb9081d6a9be17e44" + integrity sha512-FCsGHdlrOnZQcp0+XT5a+pYowf33itBalCl+7ovNXC/7o5BhIpG14M3OrpPPdBSIQJCm+0M5+9mO7S9VVTTCFw== + dependencies: + ip-regex "^5.0.0" + super-regex "^0.2.0" + is-ipfs@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/is-ipfs/-/is-ipfs-2.0.0.tgz" @@ -3044,6 +3734,11 @@ is-ipfs@2.0.0: multihashes "^3.0.1" uint8arrays "^1.1.0" +is-loopback-addr@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-loopback-addr/-/is-loopback-addr-2.0.2.tgz#70a6668fa3555d47caebdcee045745ab80adf5e4" + integrity sha512-26POf2KRCno/KTNL5Q0b/9TYnL00xEsSaLfiFRmjM7m7Lw7ZMmFybzzuX4CcsLAluZGd+niLUiMRxEooVE3aqg== + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" @@ -3064,6 +3759,11 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-regexp@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-3.1.0.tgz#0235eab9cda5b83f96ac4a263d8c32c9d5ad7422" + integrity sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" @@ -3118,6 +3818,11 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +iso-constants@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/iso-constants/-/iso-constants-0.1.2.tgz#3d2456ed5aeaa55d18564f285ba02a47a0d885b4" + integrity sha512-OTCM5ZCQsHBCI4Wdu4tSxvDIkmDHd5EwJDps5mKqnQnWJSKlnwMs3EDZ4n3Fh1tmkWkDlyd2vCDbEYuPbyrUNQ== + iso-url@~0.4.7: version "0.4.7" resolved "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz" @@ -3128,6 +3833,191 @@ isstream@~0.1.2: resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== +it-all@^3.0.0: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-all/-/it-all-3.0.6.tgz#30a4f922ae9ca0945b0f720d3478ae6f5b6707ab" + integrity sha512-HXZWbxCgQZJfrv5rXvaVeaayXED8nTKx9tj9fpBhmcUJcedVZshMMMqTj0RG2+scGypb9Ut1zd1ifbf3lA8L+Q== + +it-byte-stream@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/it-byte-stream/-/it-byte-stream-1.1.0.tgz#f5b80b713fb71a34cbff2390b7232b103cf625bb" + integrity sha512-WWponBWdKEa6o2U3NX+wGMY8X1EkWXcQvpC+3CUqKb4ZzK30q3EPqiTjFxLf9tNVgdF/MNAtx/XclpVfgaz9KQ== + dependencies: + it-queueless-pushable "^1.0.0" + it-stream-types "^2.0.1" + uint8arraylist "^2.4.8" + +it-drain@^3.0.5, it-drain@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/it-drain/-/it-drain-3.0.7.tgz#671a5d0220802c5bce9e68fc2b07088540fbc674" + integrity sha512-vy6S1JKjjHSIFHgBpLpD1zhkCRl3z1zYWUxE14+kAYf+BL9ssWSFImJfhl361IIcwr0ofw8etzg11VqqB+ntUA== + +it-filter@^3.0.2, it-filter@^3.0.4: + version "3.1.1" + resolved "https://registry.yarnpkg.com/it-filter/-/it-filter-3.1.1.tgz#d9f55ecb26200baca41e5e330e5808b3afdfa7b7" + integrity sha512-TOXmVuaSkxlLp2hXKoMTra0WMZMKVFxE3vSsbIA+PbADNCBAHhjJ/lM31vBOUTddHMO34Ku++vU8T9PLlBxQtg== + dependencies: + it-peekable "^3.0.0" + +it-first@^3.0.3, it-first@^3.0.4: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-first/-/it-first-3.0.6.tgz#f532f0f36fe9bf0c291e0162b9d3375d59fe8f05" + integrity sha512-ExIewyK9kXKNAplg2GMeWfgjUcfC1FnUXz/RPfAvIXby+w7U4b3//5Lic0NV03gXT8O/isj5Nmp6KiY0d45pIQ== + +it-foreach@^2.0.6: + version "2.1.1" + resolved "https://registry.yarnpkg.com/it-foreach/-/it-foreach-2.1.1.tgz#93e311a1057dd0ff7631f914dc9c2c963f27a4b8" + integrity sha512-ID4Gxnavk/LVQLQESAQ9hR6dR63Ih6X+8VdxEktX8rpz2dCGAbZpey/eljTNbMfV2UKXHiu6UsneoNBZuac97g== + dependencies: + it-peekable "^3.0.0" + +it-last@^3.0.2: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-last/-/it-last-3.0.6.tgz#53b1463e47fcaa950375968002598686101de6ab" + integrity sha512-M4/get95O85u2vWvWQinF8SJUc/RPC5bWTveBTYXvlP2q5TF9Y+QhT3nz+CRCyS2YEc66VJkyl/da6WrJ0wKhw== + +it-length-prefixed-stream@^1.0.0, it-length-prefixed-stream@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/it-length-prefixed-stream/-/it-length-prefixed-stream-1.2.0.tgz#1f6ad78c60dea3b16364f86a0b78058f4d66a04e" + integrity sha512-vX7dzSl/2UMYYsAr0FQdPNVR5xYEETaeboZ+eXxNBjgARuvxnWA6OedW8lC5/J3ebMTC98JhA3eH76eTijUOsA== + dependencies: + it-byte-stream "^1.0.0" + it-stream-types "^2.0.1" + uint8-varint "^2.0.4" + uint8arraylist "^2.4.8" + +it-length-prefixed@^9.0.0, it-length-prefixed@^9.0.4: + version "9.1.0" + resolved "https://registry.yarnpkg.com/it-length-prefixed/-/it-length-prefixed-9.1.0.tgz#19d5d336068fdcbbadfafb1eb33331a9370d4cac" + integrity sha512-kx2UTJuy7/lsT3QUzf50NjfxU1Z4P4wlvYp6YnR5Nc61P8XKfy+QtiJi1VLojA+Kea7vMbB4002rIij1Ol9hcw== + dependencies: + it-reader "^6.0.1" + it-stream-types "^2.0.1" + uint8-varint "^2.0.1" + uint8arraylist "^2.0.0" + uint8arrays "^5.0.1" + +it-length@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-length/-/it-length-3.0.6.tgz#4105934e10b4d5e158e11cbd7da4073fc441fcd3" + integrity sha512-R7bxHAzpRzYz7vghc2DDH7x4KXvEkeLfN/h316++jzbkEHIRXbEPLbE20p5yrqqBdOeK6/FRUDuHlTJ0H1hysw== + +it-map@^3.0.3, it-map@^3.0.4, it-map@^3.0.5, it-map@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/it-map/-/it-map-3.1.1.tgz#637877e93be93a7aa7d7fc103b70a5939fc6f7a1" + integrity sha512-9bCSwKD1yN1wCOgJ9UOl+46NQtdatosPWzxxUk2NdTLwRPXLh+L7iwCC9QKsbgM60RQxT/nH8bKMqm3H/o8IHQ== + dependencies: + it-peekable "^3.0.0" + +it-merge@^3.0.0, it-merge@^3.0.3, it-merge@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/it-merge/-/it-merge-3.0.5.tgz#2b0d1d07c825b9d20c4c2889aab8e07322fd803e" + integrity sha512-2l7+mPf85pyRF5pqi0dKcA54E5Jm/2FyY5GsOaN51Ta0ipC7YZ3szuAsH8wOoB6eKY4XsU4k2X+mzPmFBMayEA== + dependencies: + it-pushable "^3.2.3" + +it-ndjson@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/it-ndjson/-/it-ndjson-1.0.7.tgz#017e5e3e1b5fa8c10b8d9a0771bcc9b55baaa6b3" + integrity sha512-V3IskT5RCVtov1u6sC9gkg0uD02qe8yPoVzBZVaRx+YkuMdpFd6opiAwfYovNd/NEbqo9mBN8wJLtw6vD0Xiqg== + +it-parallel@^3.0.0, it-parallel@^3.0.7: + version "3.0.8" + resolved "https://registry.yarnpkg.com/it-parallel/-/it-parallel-3.0.8.tgz#fb4a5344732ddae9eff7c7b21908aa1f223638d4" + integrity sha512-URLhs6eG4Hdr4OdvgBBPDzOjBeSSmI+Kqex2rv/aAyYClME26RYHirLVhZsZP5M+ZP6M34iRlXk8Wlqtezuqpg== + dependencies: + p-defer "^4.0.1" + +it-peekable@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/it-peekable/-/it-peekable-3.0.5.tgz#63b0c750e27e2ba0c1db6d6a3496b7ef51a6547d" + integrity sha512-JWQOGMt6rKiPcY30zUVMR4g6YxkpueTwHVE7CMs/aGqCf4OydM6w+7ZM3PvmO1e0TocjuR4aL8xyZWR46cTqCQ== + +it-pipe@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/it-pipe/-/it-pipe-3.0.1.tgz#b25720df82f4c558a8532602b5fbc37bbe4e7ba5" + integrity sha512-sIoNrQl1qSRg2seYSBH/3QxWhJFn9PKYvOf/bHdtCBF0bnghey44VyASsWzn5dAx0DCDDABq1hZIuzKmtBZmKA== + dependencies: + it-merge "^3.0.0" + it-pushable "^3.1.2" + it-stream-types "^2.0.1" + +it-protobuf-stream@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/it-protobuf-stream/-/it-protobuf-stream-1.1.5.tgz#70da43abfb6beaaf7c53262d8cfd176d463b08f0" + integrity sha512-H70idW45As3cEbU4uSoZ9IYHUIV3YM69/2mmXYR7gOlPabWjuyNi3/abK11geiiq3la27Sos/mXr68JljjKtEQ== + dependencies: + it-length-prefixed-stream "^1.0.0" + it-stream-types "^2.0.1" + uint8arraylist "^2.4.8" + +it-pushable@^3.1.0, it-pushable@^3.1.2, it-pushable@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/it-pushable/-/it-pushable-3.2.3.tgz#e2b80aed90cfbcd54b620c0a0785e546d4e5f334" + integrity sha512-gzYnXYK8Y5t5b/BnJUr7glfQLO4U5vyb05gPx/TyTw+4Bv1zM9gFk4YsOrnulWefMewlphCjKkakFvj1y99Tcg== + dependencies: + p-defer "^4.0.0" + +it-queueless-pushable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/it-queueless-pushable/-/it-queueless-pushable-1.0.0.tgz#917b52964cd6465d6436f923552c407c5ee3d11c" + integrity sha512-HbcAbcuQj7a9EBxiRCZ+77FxWutgs/pY5ZvEyQnylWPGNFojCLAUwhcZjf5OuEQ9+y+vSa7w1GQBe8xJdmIn5A== + dependencies: + p-defer "^4.0.1" + race-signal "^1.0.2" + +it-reader@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/it-reader/-/it-reader-6.0.4.tgz#439cb88225dcd15116be0ffde9e846a928c3871a" + integrity sha512-XCWifEcNFFjjBHtor4Sfaj8rcpt+FkY0L6WdhD578SCDhV4VUm7fCkF3dv5a+fTcfQqvN9BsxBTvWbYO6iCjTg== + dependencies: + it-stream-types "^2.0.1" + uint8arraylist "^2.0.0" + +it-sort@^3.0.4: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-sort/-/it-sort-3.0.6.tgz#58af5dec478c411ae5adf30f90078a6fc286484d" + integrity sha512-aNrlZAXB8vWBd42tCpaXGL6CJVJNDW3OLczmdt6g0k/s9Z6evkTdgU2LjwW5SNNeX41sF+C8MjV+OcVf93PsPw== + dependencies: + it-all "^3.0.0" + +it-stream-types@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/it-stream-types/-/it-stream-types-2.0.1.tgz#69cb4d7e79e707b8257a8997e02751ccb6c3af32" + integrity sha512-6DmOs5r7ERDbvS4q8yLKENcj6Yecr7QQTqWApbZdfAUTEC947d+PEha7PCqhm//9oxaLYL7TWRekwhoXl2s6fg== + +it-take@^3.0.1, it-take@^3.0.4, it-take@^3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-take/-/it-take-3.0.6.tgz#509283b69b88f823350b256392525267609f1925" + integrity sha512-uqw3MRzf9to1SOLxaureGa73lK8k8ZB/asOApTAkvrzUqCznGtKNgPFH7uYIWlt4UuWq/hU6I+U4Fm5xpjN8Vg== + +it-tar@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/it-tar/-/it-tar-6.0.5.tgz#46bf290415aef92bb6ad831f5883a75e2f187ed0" + integrity sha512-GxKBamsX2EZA6jrNh6xoeKmRpbOELgYhCk1ojhN0TFSBdxwkRBqBRc3sI43vTHRpI7i2o6ptrSxK3LLKWNvudg== + dependencies: + iso-constants "^0.1.2" + it-reader "^6.0.1" + it-stream-types "^2.0.1" + it-to-buffer "^4.0.5" + p-defer "^4.0.0" + uint8arraylist "^2.3.2" + uint8arrays "^5.0.2" + +it-to-browser-readablestream@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/it-to-browser-readablestream/-/it-to-browser-readablestream-2.0.9.tgz#6ec4e3fb2fa090580e94d6f4dbedc6a02a6f8498" + integrity sha512-Q/0OXLOMgZ4Fk62Mrqp3x9QqN/UH9fotftr3dEfqr74Bt8ceClLOTmhkMyrk53R/gRcxdM6tBjzHGBeSjhmPeQ== + dependencies: + get-iterator "^2.0.1" + +it-to-buffer@^4.0.5: + version "4.0.7" + resolved "https://registry.yarnpkg.com/it-to-buffer/-/it-to-buffer-4.0.7.tgz#f3b10ebb4f5a146acdbd73225e8c8e0a308709c8" + integrity sha512-c7JXrFg8xntJTPzhg7Dg6WJYm+XW0wBUebvEBrc6zrL/QukGRXclw1OBz6M9Qmqkiorgb3qpsRwKlI/4Q3tmkQ== + dependencies: + uint8arrays "^5.0.3" + iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2, iterall@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz" @@ -3335,6 +4225,11 @@ lowercase-keys@^2.0.0: resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^10.2.2: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" @@ -3484,6 +4379,15 @@ module-details-from-path@^1.0.3: resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== +mortice@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/mortice/-/mortice-3.0.4.tgz#34aadef768161e9dc49a7f73637b7858bcb7c6fa" + integrity sha512-MUHRCAztSl4v/dAmK8vbYi5u1n9NZtQu4H3FsqS7qgMFQIAFw9lTpHiErd9kJpapqmvEdD1L3dUmiikifAvLsQ== + dependencies: + observable-webworkers "^2.0.1" + p-queue "^8.0.1" + p-timeout "^6.0.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" @@ -3504,6 +4408,11 @@ ms@2.1.3, ms@^2.1.1: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +ms@^3.0.0-canary.1: + version "3.0.0-canary.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-3.0.0-canary.1.tgz#c7b34fbce381492fd0b345d1cf56e14d67b77b80" + integrity sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g== + multiaddr@^8.0.0: version "8.1.2" resolved "https://registry.npmjs.org/multiaddr/-/multiaddr-8.1.2.tgz" @@ -3572,6 +4481,11 @@ multicodec@^3.0.1: uint8arrays "^3.0.0" varint "^6.0.0" +multiformats@^13.0.0, multiformats@^13.0.1, multiformats@^13.1.0: + version "13.2.2" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-13.2.2.tgz#16da153ee8b68d8c9da31b52176e90b3cd8b43ef" + integrity sha512-RWI+nyf0q64vyOxL8LbKtjJMki0sogRL/8axvklNtiTM0iFCVtHwME9w6+0P1/v4dQvsIg8A45oT3ka1t/M/+A== + multiformats@^9.4.2: version "9.9.0" resolved "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz" @@ -3604,6 +4518,11 @@ multihashes@^4.0.1: uint8arrays "^3.0.0" varint "^5.0.2" +murmurhash3js-revisited@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz#6bd36e25de8f73394222adc6e41fa3fac08a5869" + integrity sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g== + nano-json-stream-parser@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz" @@ -3624,6 +4543,11 @@ negotiator@0.6.3: resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +netmask@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" + integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== + next-tick@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz" @@ -3752,6 +4676,11 @@ oboe@2.1.5: dependencies: http-https "^1.0.0" +observable-webworkers@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/observable-webworkers/-/observable-webworkers-2.0.1.tgz#7d9086ebc567bd318b46ba0506b10cedf3813878" + integrity sha512-JI1vB0u3pZjoQKOK1ROWzp0ygxSi7Yb0iR+7UNsw4/Zn4cQ0P3R7XL38zac/Dy2tEA7Lg88/wIJTjF8vYXZ0uw== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" @@ -3788,6 +4717,31 @@ p-cancelable@^2.0.0: resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz" integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== +p-defer@^4.0.0, p-defer@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-4.0.1.tgz#d12c6d41420785ed0d162dbd86b71ba490f7f99e" + integrity sha512-Mr5KC5efvAK5VUptYEIopP1bakB85k2IWXaRC0rsh1uwn1L6M0LVml8OIQ4Gudg4oyZakf7FmeRLkMMtZW1i5A== + +p-event@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-6.0.1.tgz#8f62a1e3616d4bc01fce3abda127e0383ef4715b" + integrity sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w== + dependencies: + p-timeout "^6.1.2" + +p-queue@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-8.0.1.tgz#718b7f83836922ef213ddec263ff4223ce70bef8" + integrity sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA== + dependencies: + eventemitter3 "^5.0.1" + p-timeout "^6.1.2" + +p-timeout@^6.0.0, p-timeout@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-6.1.2.tgz#22b8d8a78abf5e103030211c5fc6dee1166a6aa5" + integrity sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ== + packet-reader@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz" @@ -3956,6 +4910,11 @@ process@^0.11.10: resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== +progress-events@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/progress-events/-/progress-events-1.0.1.tgz#693b6d4153f08c1418ae3cd5fcad8596c91db7e8" + integrity sha512-MOzLIwhpt64KIVN64h1MwdKWiyKFNc/S6BoYKPIVUHFg0/eIEyBulhWCgn678v/4c0ri3FdGuzXymNCv02MUIw== + protobufjs@^7.2.3, protobufjs@^7.2.4: version "7.2.6" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.6.tgz#4a0ccd79eb292717aacf07530a07e0ed20278215" @@ -3974,6 +4933,15 @@ protobufjs@^7.2.3, protobufjs@^7.2.4: "@types/node" ">=13.7.0" long "^5.0.0" +protons-runtime@^5.0.0, protons-runtime@^5.2.1, protons-runtime@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/protons-runtime/-/protons-runtime-5.5.0.tgz#ea06d9ef843aad77ea5de3e1ebafa81b58c24570" + integrity sha512-EsALjF9QsrEk6gbCx3lmfHxVN0ah7nG3cY7GySD4xf4g8cr7g543zB88Foh897Sr1RQJ9yDCUsoT1i1H/cVUFA== + dependencies: + uint8-varint "^2.0.2" + uint8arraylist "^2.4.3" + uint8arrays "^5.0.1" + proxy-addr@~2.0.5, proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" @@ -4032,6 +5000,18 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== +pvtsutils@^1.3.2: + version "1.3.5" + resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.5.tgz#b8705b437b7b134cd7fd858f025a23456f1ce910" + integrity sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA== + dependencies: + tslib "^2.6.1" + +pvutils@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3" + integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ== + qs@6.11.0: version "6.11.0" resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" @@ -4073,6 +5053,16 @@ quick-lru@^5.1.1: resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== +race-event@^1.2.0, race-event@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/race-event/-/race-event-1.3.0.tgz#854f34118c31addf877898bd9f8e4dcfac9de7a2" + integrity sha512-kaLm7axfOnahIqD3jQ4l1e471FIFcEGebXEnhxyLscuUzV8C94xVHtWEqDDXxll7+yu/6lW0w1Ff4HbtvHvOHg== + +race-signal@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/race-signal/-/race-signal-1.1.0.tgz#8bfc0740e7dedb9488f90f98858135c7cfe51bd4" + integrity sha512-VqsW1uzCXfKBd2DhA3K3NhQlqQr04+5WQ7+kHpf1HzT01Q+ePSFWZdQHXKZPuLmm2eXTZM1XLO76cq15ZRAaEA== + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" @@ -4413,10 +5403,10 @@ shadow-cljs-jar@1.3.4: resolved "https://registry.yarnpkg.com/shadow-cljs-jar/-/shadow-cljs-jar-1.3.4.tgz#0939d91c468b4bc5eab5a958f79e7ef5696fdf62" integrity sha512-cZB2pzVXBnhpJ6PQdsjO+j/MksR28mv4QD/hP/2y1fsIa9Z9RutYgh3N34FZ8Ktl4puAXaIGlct+gMCJ5BmwmA== -shadow-cljs@2.26.2: - version "2.26.2" - resolved "https://registry.yarnpkg.com/shadow-cljs/-/shadow-cljs-2.26.2.tgz#c9d443940d679c33696009598b01e02a176f6a67" - integrity sha512-xBJxBxSpfoVQLSDA+WN+ZgtnyA5qYf3EE4ARZpov0JOz0YBTdIQajnNYMs5+5OzCbbNfhWGLybyu/Pj4dIwsWw== +shadow-cljs@2.28.16: + version "2.28.16" + resolved "https://registry.yarnpkg.com/shadow-cljs/-/shadow-cljs-2.28.16.tgz#0f705970530cc888ef246cbab87a3d07155328ef" + integrity sha512-6b4V287V0MeZUG+yUxnfCfuVCG1F4sVtpB+KcoDKtZSJIrAjBb1vkZTx/DFct0gYb0WYD5VAPVTzoGy7H+lMFg== dependencies: node-libs-browser "^2.2.1" readline-sync "^1.4.7" @@ -4487,6 +5477,11 @@ source-map@^0.6.0: resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sparse-array@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/sparse-array/-/sparse-array-1.3.2.tgz#0e1a8b71706d356bc916fe754ff496d450ec20b0" + integrity sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg== + split2@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz" @@ -4617,6 +5612,15 @@ subscriptions-transport-ws@^0.9.16, subscriptions-transport-ws@^0.9.19: symbol-observable "^1.0.4" ws "^5.2.0 || ^6.0.0 || ^7.0.0" +super-regex@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/super-regex/-/super-regex-0.2.0.tgz#dc1e071e55cdcf56930eb6271f73653a655b2642" + integrity sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw== + dependencies: + clone-regexp "^3.0.0" + function-timeout "^0.1.0" + time-span "^5.1.0" + supports-color@^4.0.0: version "4.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz" @@ -4624,6 +5628,11 @@ supports-color@^4.0.0: dependencies: has-flag "^2.0.0" +supports-color@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.4.0.tgz#17bfcf686288f531db3dea3215510621ccb55954" + integrity sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw== + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -4685,6 +5694,13 @@ tar@^4.0.2: safe-buffer "^5.2.1" yallist "^3.1.1" +time-span@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/time-span/-/time-span-5.1.0.tgz#80c76cf5a0ca28e0842d3f10a4e99034ce94b90d" + integrity sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA== + dependencies: + convert-hrtime "^5.0.0" + timed-out@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz" @@ -4697,6 +5713,11 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +timestamp-nano@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/timestamp-nano/-/timestamp-nano-1.0.1.tgz#be6eb118719504fcc3c7c732d2c461d3dd87da63" + integrity sha512-4oGOVZWTu5sl89PtCDnhQBSt7/vL1zVEwAfxH1p49JhTosxzVQWYBYFRFZ8nJmo0G6f824iyP/44BFAwIoKvIA== + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz" @@ -4757,6 +5778,11 @@ tslib@^2.3.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.4.0, tslib@^2.6.1: + version "2.6.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz" @@ -4823,6 +5849,21 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +uint8-varint@^2.0.1, uint8-varint@^2.0.2, uint8-varint@^2.0.3, uint8-varint@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/uint8-varint/-/uint8-varint-2.0.4.tgz#85be52b3849eb30f2c3640a2df8a14364180affb" + integrity sha512-FwpTa7ZGA/f/EssWAb5/YV6pHgVF1fViKdW8cWaEarjB8t7NyofSWBdOTyFPaGuUG4gx3v1O3PQ8etsiOs3lcw== + dependencies: + uint8arraylist "^2.0.0" + uint8arrays "^5.0.0" + +uint8arraylist@^2.0.0, uint8arraylist@^2.3.2, uint8arraylist@^2.4.3, uint8arraylist@^2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/uint8arraylist/-/uint8arraylist-2.4.8.tgz#5a4d17f4defd77799cb38e93fd5db0f0dceddc12" + integrity sha512-vc1PlGOzglLF0eae1M8mLRTBivsvrGsdmJ5RbK3e+QRvRLOZfZhQROTwH/OfyF3+ZVUg9/8hE8bmKP2CvP9quQ== + dependencies: + uint8arrays "^5.0.1" + uint8arrays@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/uint8arrays/-/uint8arrays-1.1.0.tgz" @@ -4845,6 +5886,13 @@ uint8arrays@^3.0.0: dependencies: multiformats "^9.4.2" +uint8arrays@^5.0.0, uint8arrays@^5.0.1, uint8arrays@^5.0.2, uint8arrays@^5.0.3, uint8arrays@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-5.1.0.tgz#14047c9bdf825d025b7391299436e5e50e7270f1" + integrity sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww== + dependencies: + multiformats "^13.0.0" + ultron@~1.1.0: version "1.1.1" resolved "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz" @@ -5004,6 +6052,14 @@ vm-browserify@^1.0.1: resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +weald@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/weald/-/weald-1.0.2.tgz#a51fb3a8dbf5fa2b71ef09f9a267c86a46742238" + integrity sha512-iG5cIuBwsPe1ZcoGGd4X6QYlepU1vLr4l4oWpzQWqeJPSo9B8bxxyE6xlnj3TCmThtha7gyVL+uuZgUFkPyfDg== + dependencies: + ms "^3.0.0-canary.1" + supports-color "^9.4.0" + web-encoding@^1.0.2, web-encoding@^1.0.6: version "1.1.5" resolved "https://registry.npmjs.org/web-encoding/-/web-encoding-1.1.5.tgz" diff --git a/shared/src/ethlance/shared/smart_contracts_qa.cljs b/shared/src/ethlance/shared/smart_contracts_qa.cljs index bd8a1f90..2118666b 100644 --- a/shared/src/ethlance/shared/smart_contracts_qa.cljs +++ b/shared/src/ethlance/shared/smart_contracts_qa.cljs @@ -1,13 +1,31 @@ (ns ethlance.shared.smart-contracts-qa) +; Contract addresses deployed to Base Sepolia testnet +; FIXME: currently QA deploy reads these although works against Base (and not Arbitrum) +; It should be changed either by +; 1) setting ETHLANCE_ENV=qa-base during ui & server compilation +; 2) or change truffle config and when deploying contracts use ETHLANCE_ENV=qa +; during contract compilation & deployment (def smart-contracts - {:token {:name "TestToken" :address "0xC7B869260BdB1516a638A3ae05FBb4EF2496849F"} - :test-nft {:name "TestNft" :address "0x06E8636ee84fe530b06997e33C9Fa9ec7738e27C"} - :test-multi-token {:name "TestMultiToken" :address "0x09435f3a6c2fE5F5A584Dc7FD0901BebA70Ab19E"} - :ethlance-structs {:name "EthlanceStructs" :address "0xFd4B3f52cCD68eFB392367cf0AFdd4e8f32f2a4e"} - :job-helpers {:name "JobHelpers" :address "0xE1e2B5770Dc32F4B361f2D15d544e7Ca76B04a62"} - :job {:name "Job" :address "0x6F6591AB41C7f5dC2D514c12D7f42dE5fD169aF4"} - :mutable-forwarder {:name "MutableForwarder" :address "0xeA2370de1d4Ab6b99C7B7420b625bE013200Bb21"} - :ethlance {:name "EthlanceProxy" :address "0xb9232E80982072316D6Ef3a14B5D9a79cc65aAb1" :forwards-to :ethlance-impl} - :ethlance-impl {:name "Ethlance" :address "0xFD219a291bD559540d9E50835cD2529a16c56aac"}}) + {:token {:name "TestToken" :address "0xEC0eBe108Cb18E2e3E086D95ec0e54186515D28c"} + :test-nft {:name "TestNft" :address "0xba626CF0E8DE6589DCC3366a83A328c2EfF1aB16"} + :test-multi-token {:name "TestMultiToken" :address "0x1427FFB41C054FE0a46Fd815eEa38A25D853c89F"} + :ethlance-structs {:name "EthlanceStructs" :address "0xB7BD1c448b5Bf92C3Bb6Fa67b972fa4a822e9C4D"} + :job-helpers {:name "JobHelpers" :address "0x997A67E6Ca104bbFB441cb852aDC1d9f93a330Ba"} + :job {:name "Job" :address "0xf886242c1A9767189eFc95d9863706dD86698CA8"} + :mutable-forwarder {:name "MutableForwarder" :address "0xB220d6e2f1CCFa96f197bf735368b06B9587a48f"} + :ethlance {:name "EthlanceProxy" :address "0x7118b32BFCB003deB251f4265bfC2783C64696a8" :forwards-to :ethlance-impl} + :ethlance-impl {:name "Ethlance" :address "0x9cDb54eF2e9bC741be383Aed1A9cD63e1537DBFd"}}) + +; Contract addresses deployed to Arbitrum Sepolia testnet +; (def smart-contracts +; {:token {:name "TestToken" :address "0xC7B869260BdB1516a638A3ae05FBb4EF2496849F"} +; :test-nft {:name "TestNft" :address "0x06E8636ee84fe530b06997e33C9Fa9ec7738e27C"} +; :test-multi-token {:name "TestMultiToken" :address "0x09435f3a6c2fE5F5A584Dc7FD0901BebA70Ab19E"} +; :ethlance-structs {:name "EthlanceStructs" :address "0xFd4B3f52cCD68eFB392367cf0AFdd4e8f32f2a4e"} +; :job-helpers {:name "JobHelpers" :address "0xE1e2B5770Dc32F4B361f2D15d544e7Ca76B04a62"} +; :job {:name "Job" :address "0x6F6591AB41C7f5dC2D514c12D7f42dE5fD169aF4"} +; :mutable-forwarder {:name "MutableForwarder" :address "0xeA2370de1d4Ab6b99C7B7420b625bE013200Bb21"} +; :ethlance {:name "EthlanceProxy" :address "0xb9232E80982072316D6Ef3a14B5D9a79cc65aAb1" :forwards-to :ethlance-impl} +; :ethlance-impl {:name "Ethlance" :address "0xFD219a291bD559540d9E50835cD2529a16c56aac"}}) diff --git a/shared/src/ethlance/shared/smart_contracts_qa_base.cljs b/shared/src/ethlance/shared/smart_contracts_qa_base.cljs new file mode 100644 index 00000000..378bc63a --- /dev/null +++ b/shared/src/ethlance/shared/smart_contracts_qa_base.cljs @@ -0,0 +1,12 @@ +(ns ethlance.shared.smart-contracts-qa-base) + +(def smart-contracts + {:token {:name "TestToken" :address "0xEC0eBe108Cb18E2e3E086D95ec0e54186515D28c"} + :test-nft {:name "TestNft" :address "0xba626CF0E8DE6589DCC3366a83A328c2EfF1aB16"} + :test-multi-token {:name "TestMultiToken" :address "0x1427FFB41C054FE0a46Fd815eEa38A25D853c89F"} + :ethlance-structs {:name "EthlanceStructs" :address "0xB7BD1c448b5Bf92C3Bb6Fa67b972fa4a822e9C4D"} + :job-helpers {:name "JobHelpers" :address "0x997A67E6Ca104bbFB441cb852aDC1d9f93a330Ba"} + :job {:name "Job" :address "0xf886242c1A9767189eFc95d9863706dD86698CA8"} + :mutable-forwarder {:name "MutableForwarder" :address "0xB220d6e2f1CCFa96f197bf735368b06B9587a48f"} + :ethlance {:name "EthlanceProxy" :address "0x7118b32BFCB003deB251f4265bfC2783C64696a8" :forwards-to :ethlance-impl} + :ethlance-impl {:name "Ethlance" :address "0x9cDb54eF2e9bC741be383Aed1A9cD63e1537DBFd"}}) diff --git a/truffle-config.js b/truffle-config.js index ffcbe298..be6b44a7 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -2,10 +2,13 @@ const ETHLANCE_ENV = process.env.ETHLANCE_ENV || "dev"; const ETHLANCE_MNEMONIC = process.env.ETHLANCE_MNEMONIC; const ETHLANCE_ETH_NODE_ADDRESS = process.env.ETHLANCE_ETH_NODE_ADDRESS; +const ETHLANCE_DEPLOYER_ADDRESS = process.env.ETHLANCE_DEPLOYER_ADDRESS +const ETHLANCE_DEPLOY_SEED = process.env.ETHLANCE_DEPLOY_SEED const smartContractsPaths = { "dev" : '/shared/src/ethlance/shared/smart_contracts_dev.cljs', "qa" : '/shared/src/ethlance/shared/smart_contracts_qa.cljs', + "qa-base" : '/shared/src/ethlance/shared/smart_contracts_qa_base.cljs', "prod" :'/shared/src/ethlance/shared/smart_contracts_prod.cljs' }; @@ -89,7 +92,16 @@ module.exports = { gasPrice: 20e9, // 20 gwei, default for ganache network_id: 421614, from: "0x642fAE80d3C74559A18B0558A518cDBF6b047968" // 1st address - } + }, + "base-sepolia": { + provider: new HDWalletProvider({mnemonic: {phrase: ETHLANCE_DEPLOY_SEED}, + providerOrUrl: ETHLANCE_ETH_NODE_ADDRESS || 'https://sepolia.base.org' + }), + gas: 6e6, // gas limit + gasPrice: 20e9, // 20 gwei, default for ganache + network_id: 84532, + from: ETHLANCE_DEPLOYER_ADDRESS + } } } diff --git a/ui/deps.edn b/ui/deps.edn index 18abe357..6ae7c515 100644 --- a/ui/deps.edn +++ b/ui/deps.edn @@ -1,7 +1,7 @@ {:paths ["src" "test" "resources" "src-cljsjs"] :deps - {org.clojure/clojure {:mvn/version "1.10.3"}, - org.clojure/clojurescript {:mvn/version "1.11.60"} + {org.clojure/clojure {:mvn/version "1.12.0"}, + org.clojure/clojurescript {:mvn/version "1.11.132"} binaryage/devtools {:mvn/version "1.0.7"} re-frame/re-frame {:mvn/version "1.3.0"} @@ -81,7 +81,7 @@ :aliases {:shadow-cljs {:extra-deps - {thheller/shadow-cljs {:mvn/version "2.26.2"}}, + {thheller/shadow-cljs {:mvn/version "2.28.16"}}, :main-opts ["-m" "shadow.cljs.devtools.cli"]} :local-deps {:override-deps @@ -93,7 +93,7 @@ is.d0x/district-ui-router {:local/root "../../d0x-libs/browser/district-ui-router"} is.d0x/district-ui-web3-accounts {:local/root "../../d0x-libs/browser/district-ui-web3-accounts"} is.d0x/re-frame-web3-fx {:local/root "../../d0x-libs/browser/re-frame-web3-fx"} - is.d0x/cljs-ipfs-http-client {:local/root "../../d0x-libs/shared/cljs-ipfs-http-client"} + ; is.d0x/cljs-ipfs-http-client {:local/root "../../d0x-libs/shared/cljs-ipfs-http-client"} is.d0x/district-ui-web3-tx {:local/root "../../d0x-libs/browser/district-ui-web3-tx"}}} :dev {:extra-deps diff --git a/ui/package.json b/ui/package.json index bf67d4ff..a3887edb 100644 --- a/ui/package.json +++ b/ui/package.json @@ -23,7 +23,7 @@ "react-transition-group": "^4.4.5", "semantic-ui-css": "^2.5.0", "semantic-ui-react": "^2.1.4", - "shadow-cljs": "2.26.2", + "shadow-cljs": "2.28.16", "simplebar": "^5.3.9", "web3": "1.7.3", "xhr2": "0.2.1", diff --git a/ui/resources/public/less/component/search-input.less b/ui/resources/public/less/component/search-input.less index 5cf75b1a..a15b87ef 100644 --- a/ui/resources/public/less/component/search-input.less +++ b/ui/resources/public/less/component/search-input.less @@ -44,7 +44,7 @@ align-items: center; background-color: #color[purple]; cursor: pointer; - + &:hover { background-color: #color[dark-blue]; } @@ -78,7 +78,7 @@ align-items: center; height: @container-height; border-top: 2px solid #dfdfdf; - + &:first-child { border-top: 1px solid white; } @@ -103,7 +103,7 @@ align-items: center; background-color: white; padding: 0.5em 1.0em; - margin: 0em 0.3em 0em 0.3em; + margin: 0em 0.3em 0.3em 0.3em; border-radius: 5px; @media #media[mobile-query] { diff --git a/ui/resources/public/less/page/about.less b/ui/resources/public/less/page/about.less index 2910fe98..fb851265 100644 --- a/ui/resources/public/less/page/about.less +++ b/ui/resources/public/less/page/about.less @@ -2,5 +2,15 @@ .about-main-container { + .title { + font-size: 2em; + } + .description { + font-size: 1em; + p { + margin: 1em; + line-height: normal; + } + } } diff --git a/ui/resources/public/less/page/how-it-works.less b/ui/resources/public/less/page/how-it-works.less index 6c725ece..a7c4ca34 100644 --- a/ui/resources/public/less/page/how-it-works.less +++ b/ui/resources/public/less/page/how-it-works.less @@ -2,5 +2,14 @@ .how-it-works-main-container { - + .title { + font-size: 2em; + } + .description { + font-size: 1em; + p { + margin: 1em; + line-height: normal; + } + } } diff --git a/ui/src/ethlance/ui/component/carousel.cljs b/ui/src/ethlance/ui/component/carousel.cljs index aaa16149..55451100 100644 --- a/ui/src/ethlance/ui/component/carousel.cljs +++ b/ui/src/ethlance/ui/component/carousel.cljs @@ -60,19 +60,23 @@ (defn c-feedback-slide - [{:keys [id rating author text image-url class]}] - [:div.feedback-slide - ;; FIXME: use better unique key - {:key (str "feedback-" id "-" rating) :class class} - [:div.profile-image [c-profile-image {:src image-url}]] - [:div.rating [c-rating {:rating rating :color :white}]] - [:div.message text] - [:div.name author]]) + [{:keys [id rating author text image-url class link-params]}] + (let [slide-content [:div.feedback-slide + ;; FIXME: use better unique key + {:key (str "feedback-" id "-" rating) :class class} + [:div.profile-image [c-profile-image {:src image-url}]] + [:div.rating [c-rating {:rating rating :color :white}]] + [:div.message text] + [:div.name author]]] + (if link-params + [:a link-params slide-content] + slide-content)) + ) (defn c-carousel [{:keys []} & children] - [:div.ethlance-new-carousel + [:div.ethlance-new-carousel {:style {:height "22em"}} [:> react-carousel/CarouselProvider {:natural-slide-width 388 :natural-slide-height 300 :total-slides (count children) diff --git a/ui/src/ethlance/ui/component/tabular_layout.cljs b/ui/src/ethlance/ui/component/tabular_layout.cljs index bc22fadf..e30fe25b 100644 --- a/ui/src/ethlance/ui/component/tabular_layout.cljs +++ b/ui/src/ethlance/ui/component/tabular_layout.cljs @@ -56,6 +56,8 @@ tab-options (map-indexed #(-> %2 first (assoc :index %1)) tab-parts) tab-children (mapv second tab-parts) tab-count-class (str "tab-count-" (count tab-children))] + (when (>= @*active-tab-index (count tab-parts)) + (reset! *active-tab-index (or default-tab 0))) [:div.tabular-layout opts [:div.tab-listing {:class tab-count-class} diff --git a/ui/src/ethlance/ui/config.cljs b/ui/src/ethlance/ui/config.cljs index 74abf2e8..de48e004 100644 --- a/ui/src/ethlance/ui/config.cljs +++ b/ui/src/ethlance/ui/config.cljs @@ -7,6 +7,7 @@ [ethlance.shared.smart-contracts-dev :as smart-contracts-dev] [ethlance.shared.smart-contracts-prod :as smart-contracts-prod] [ethlance.shared.smart-contracts-qa :as smart-contracts-qa] + [ethlance.shared.smart-contracts-qa-base :as smart-contracts-qa-base] [ethlance.shared.utils :include-macros true :as shared-utils])) @@ -32,7 +33,10 @@ (condp = environment "prod" smart-contracts-prod/smart-contracts "qa" smart-contracts-qa/smart-contracts - "dev" smart-contracts-dev/smart-contracts)) + "qa-base" smart-contracts-qa-base/smart-contracts + "dev" smart-contracts-dev/smart-contracts + ; "dev" smart-contracts-qa-base/smart-contracts + )) (def default-config @@ -61,10 +65,6 @@ :load-method :request :contracts contracts-var} :root-url "http://d0x-vm:6500" - :github - {:client-id "83e6a6043ca4ae50f8b0"} - :linkedin - {:client-id "86csctqngadad5"} :conversion-rates {:from-currencies [:ETH :USD] :to-currencies [:USD :ETH]}}) @@ -78,6 +78,10 @@ (def config-qa {:server-config {:url "https://ethlance-api.qa.district0x.io/config"}}) +(def config-qa-base + {:server-config {:url "https://ethlance-qa.mad.is/config"}}) + + (def config-prod {:server-config {:url "http://api.ethlance.com"}}) @@ -91,4 +95,5 @@ (case env "dev" config-dev "qa" config-qa + "qa-base" config-qa-base "prod" config-prod)))) diff --git a/ui/src/ethlance/ui/page/about.cljs b/ui/src/ethlance/ui/page/about.cljs index 631afec0..7a19d116 100644 --- a/ui/src/ethlance/ui/page/about.cljs +++ b/ui/src/ethlance/ui/page/about.cljs @@ -1,10 +1,15 @@ (ns ethlance.ui.page.about (:require [district.ui.component.page :refer [page]] - [ethlance.ui.component.main-layout :refer [c-main-layout]])) + [ethlance.ui.component.main-layout :refer [c-main-layout]] + [ethlance.ui.util.content-helpers :refer [page-with-title]])) +(def description + "The district0x network is a collective of decentralized marketplaces and communities known as ‘Districts’. Districts exist on top of a modular framework of Ethereum smart contracts and frontend libraries referred to as d0xINFRA. + The district0x network solves a number of coordination issues and inefficiencies commonly found within distributed community marketplaces. This is accomplished by providing tools that can better align incentives and decision making among the market participants themselves. The end goal is to create a self sustaining ecosystem that can flourish without the need for a central authority.") + (defmethod page :route.misc/about [] (fn [] [c-main-layout {:container-opts {:class :about-main-container}} - "About"])) + (page-with-title "About" description)])) diff --git a/ui/src/ethlance/ui/page/how_it_works.cljs b/ui/src/ethlance/ui/page/how_it_works.cljs index 69b40262..d51616b3 100644 --- a/ui/src/ethlance/ui/page/how_it_works.cljs +++ b/ui/src/ethlance/ui/page/how_it_works.cljs @@ -1,10 +1,18 @@ (ns ethlance.ui.page.how-it-works (:require [district.ui.component.page :refer [page]] - [ethlance.ui.component.main-layout :refer [c-main-layout]])) + [ethlance.ui.component.main-layout :refer [c-main-layout]] + [ethlance.ui.util.content-helpers :refer [page-with-title]])) + + +(def description + (str + "The free market is an economic system where the prices of goods and services are determined by unrestricted competition between privately owned businesses. In this system, supply and demand dictate production decisions and pricing, allowing consumers and producers to engage freely without significant government intervention. Businesses respond to consumer preferences, leading to an efficient allocation of resources as they strive to meet market needs. + Competition is a cornerstone of the free market, driving innovation and quality improvement. Companies compete to offer better products and services at lower prices to attract consumers. This competitive environment encourages efficiency and technological advancements, which can lead to overall economic growth and increased standards of living. Entrepreneurs have the freedom to enter markets, fostering diversity and choice for consumers. + However, for a free market to function effectively, certain legal frameworks must be in place, such as property rights and contract enforcement. While the free market promotes efficiency and innovation, it can also result in challenges like income inequality and market failures if left entirely unchecked. Therefore, some level of regulation is often considered necessary to address issues like monopolies, externalities, and to protect consumers and workers, balancing freedom with societal welfare.")) (defmethod page :route.misc/how-it-works [] (fn [] [c-main-layout {:container-opts {:class :how-it-works-main-container}} - "How It Works"])) + (page-with-title "How It Works" description)])) diff --git a/ui/src/ethlance/ui/page/job_contract.cljs b/ui/src/ethlance/ui/page/job_contract.cljs index 096a5a13..03c0adfd 100644 --- a/ui/src/ethlance/ui/page/job_contract.cljs +++ b/ui/src/ethlance/ui/page/job_contract.cljs @@ -222,7 +222,12 @@ messages-result (re/subscribe [::gql/query {:queries [messages-query]} {:refetch-on #{:page.job-contract/refetch-messages}}]) - graphql-data-ready? (get-in @messages-result [:job-story :job-story/invoices])] + ; Heuristic to know that exactly the data for this query arrived + ; This is because the different GQL requests made from the same + ; page trigger the same ratoms + message-fields-to-check [:proposal-message :invitation-message] + graphql-data-ready? (some (comp not nil?) + (map #(get-in @messages-result [:job-story %]) message-fields-to-check))] (when graphql-data-ready? [c-chat-log (extract-chat-messages (:job-story @messages-result) active-user involved-users)]))) @@ -396,7 +401,6 @@ [c-button {:color :primary :on-click #(re/dispatch [:page.job-contract/accept-invitation {:text @text - :to (:employer message-params) :job-story/id @job-story-id}])} [c-button-label "Accept Invitation"]]])) @@ -664,14 +668,17 @@ (let [job-story-id (-> @*active-page-params :job-story-id parse-int) active-user (:user/id @(re/subscribe [:ethlance.ui.subscriptions/active-session])) query [:job-story {:job-story/id job-story-id} - [:job/id + [:job-story/proposal-rate + :job/id :job-story/id :job-story/status [:candidate [:user/id [:user [:user/name]]]] [:proposal-message - [:message/id :message/text]] + [:message/id + :message/text + [:creator [:user/id :user/name :user/profile-image]]]] [:job [:job/title :balance diff --git a/ui/src/ethlance/ui/page/job_contract/events.cljs b/ui/src/ethlance/ui/page/job_contract/events.cljs index 17c80335..078932b5 100644 --- a/ui/src/ethlance/ui/page/job_contract/events.cljs +++ b/ui/src/ethlance/ui/page/job_contract/events.cljs @@ -122,12 +122,10 @@ [{:keys [db]} [_event-name params]] (let [job-story-id (:job-story/id params) text (:text params) - to (:to params) mutation-params {:job-story/id job-story-id :job-story-message/type :accept-invitation :message/type :job-story-message - :text text - :to to}] + :text text}] {:db (clear-forms db) :fx [[:dispatch [::gql-events/mutation {:queries [[:send-message mutation-params]] diff --git a/ui/src/ethlance/ui/page/job_detail.cljs b/ui/src/ethlance/ui/page/job_detail.cljs index 3fecd2f5..687c0514 100644 --- a/ui/src/ethlance/ui/page/job_detail.cljs +++ b/ui/src/ethlance/ui/page/job_detail.cljs @@ -7,7 +7,7 @@ [district.ui.graphql.subs :as gql] [ethlance.shared.utils :refer [ilike!= ilike=]] [ethlance.ui.component.button :refer [c-button c-button-label]] - [ethlance.ui.component.carousel :refer [c-carousel-old c-feedback-slide]] + [ethlance.ui.component.carousel :refer [c-carousel c-feedback-slide]] [ethlance.ui.component.info-message :refer [c-info-message]] [ethlance.ui.component.loading-spinner :refer [c-loading-spinner]] [ethlance.ui.component.main-layout :refer [c-main-layout]] @@ -93,8 +93,10 @@ [:items [:feedback/rating :feedback/text :feedback/date-created - [:feedback/from-user [:user/name - :user/profile-image]]]]]]]]]] + [:feedback/from-user + [:user/id + :user/name + :user/profile-image]]]]]]]]]] result @(re/subscribe [::gql/query {:queries [feedback-query]}]) feedback-raw (get-in result [:job :job/employer :employer/feedback :items]) @@ -103,13 +105,16 @@ :rating (:feedback/rating feedback) :text (:feedback/text feedback) :author (-> feedback :feedback/from-user :user/name) - :image-url (-> feedback :feedback/from-user :user/profile-image)}) + :image-url (-> feedback :feedback/from-user :user/profile-image) + :link-params (link-params + {:route :route.user/profile + :params {:address (get-in feedback [:feedback/from-user :user/id])}})}) feedback-raw)] [:div.feedback-listing [:div.label "Feedback for employer"] (if (empty? feedback) [:label "No feedback yet for this employer"] - (into [c-carousel-old {}] (map #(c-feedback-slide %) feedback)))])) + (into [c-carousel {}] (map #(c-feedback-slide %) feedback)))])) (defn c-proposals-section @@ -180,7 +185,7 @@ :disabled (not can-send-proposals?) :on-change #(re/dispatch [:page.job-detail/set-proposal-token-amount %])}] [:label.post-label token-display-name]] - [:label "The amount is for payment type: " (util.job/get-in-pair-vector util.job/bid-option *bid-option)] + [:label {:style {:margin-top "1em" :margin-bottom "1em"}} (util.job/get-in-pair-vector util.job/bid-option *bid-option)] [:div.description-input [c-textarea-input {:disabled (not can-send-proposals?) @@ -243,18 +248,18 @@ [:div.proposal-form [:div.label "Accept arbiter quote"] [:div.amount-input - [:div.label "Arbiter: "] + [:div.label {:style {:margin-right "1em"}} "Arbiter: "] [c-text-input {:placeholder "" :disabled true :value (get-in arbitration-to-accept [:arbiter :user :user/name])}]] [:div.amount-input - [:div.label "Amount: "] + [:div.label {:style {:margin-right "1em"}} "Amount: "] [c-text-input {:placeholder "" :disabled true :value (token-utils/human-amount (get arbitration-to-accept :arbitration/fee) :eth)}] - [:label "ETH (Ether)"]] + [:label "ETH"]] (when arbiter-to-be-assigned? [c-button {:style (when (nil? arbitration-to-accept) {:background :gray}) @@ -524,6 +529,7 @@ token-details token-id (:token-amount amount)]))) + :style {:margin-top "1em"} :disabled? @add-funds-tx-in-progress? :size :small} [c-button-label "Confirm"]]] diff --git a/ui/src/ethlance/ui/page/new_job.cljs b/ui/src/ethlance/ui/page/new_job.cljs index 825965da..8d775140 100644 --- a/ui/src/ethlance/ui/page/new_job.cljs +++ b/ui/src/ethlance/ui/page/new_job.cljs @@ -211,7 +211,7 @@ (defn c-invite-to-create-employer-profile [] [c-main-layout {:container-opts {:class :new-job-main-container}} - [:div "Set up your employer profile to be able to create new jobs"] + [:div {:style {:margin "2em"}} "Set up your employer profile to be able to create new jobs"] [:div.button {:on-click (navigation/create-handler {:route :route.me/sign-up :query {:tab "employer"}})} "Go to employer profile page"]]) diff --git a/ui/src/ethlance/ui/page/new_job/events.cljs b/ui/src/ethlance/ui/page/new_job/events.cljs index e156e59c..b1537880 100644 --- a/ui/src/ethlance/ui/page/new_job/events.cljs +++ b/ui/src/ethlance/ui/page/new_job/events.cljs @@ -1,5 +1,6 @@ (ns ethlance.ui.page.new-job.events (:require + [cljs.core.async :as async :refer [hex js-obj->clj-map]] [ethlance.ui.event.utils :as event.utils] + [ethlance.ui.util.tokens :as util.tokens] [re-frame.core :as re])) @@ -164,16 +166,60 @@ (assoc-in db [state-key :tx-in-progress?] in-progress?)) +(re/reg-event-fx + ::job-to-ipfs-success + (fn [cofx event] + (println ">>> :job-to-ipfs-success") + (let [creator (accounts-queries/active-account (:db cofx)) + job-fields (get-in cofx [:db state-key]) + token-type (:job/token-type job-fields) + token-amount (if (= token-type :erc721) + 1 + (get-in job-fields [:job/token-amount :token-amount])) + address-placeholder "0x0000000000000000000000000000000000000000" + token-address (if (not (= token-type :eth)) + (:job/token-address job-fields) + address-placeholder) + offered-value {:value (str token-amount) + :token + {:tokenId (:job/token-id job-fields) + :tokenContract + {:tokenType (contract-constants/token-type->enum-val token-type) + :tokenAddress token-address}}} + invited-arbiters (if (:job/with-arbiter? job-fields) + (into [] (:job/invited-arbiters job-fields)) + []) + new-job-params {:offered-value offered-value + :token-type token-type + :employer creator + :arbiters invited-arbiters + :ipfs-hash (base58->hex (get-in event [1 :Hash]))} + next-event {:eth ::send-create-job-tx + :erc20 ::ensure-erc20-allowance + :erc721 ::safe-transfer-with-create-job + :erc1155 ::safe-transfer-with-create-job}] + {:db (assoc-in (:db cofx) new-job-params-path new-job-params) + :fx [[:dispatch [(get next-event token-type)]]]}))) + + +(re/reg-event-fx + ::job-to-ipfs-failure + (fn [{:keys [db]} _] + (println ">>> :job-to-ipfs-failure") + {:db (set-tx-in-progress db false) + :dispatch [::notification.events/show "Error with loading new job data to IPFS"]})) + + (re/reg-event-fx :page.new-job/create [interceptors] (fn [{:keys [db]}] (let [db-job (get db state-key) ipfs-job (reduce-kv (partial db-job->ipfs-job db-job) {} db->ipfs-mapping)] - {:ipfs/call {:func "add" - :args [(js/Blob. [ipfs-job])] - :on-success [::job-to-ipfs-success] - :on-error [::job-to-ipfs-failure]}}))) + {:fx [[:ipfs/call {:func "add" + :args [(js/Blob. [ipfs-job])] + :on-success [::job-to-ipfs-success] + :on-error [::job-to-ipfs-failure]}]]}))) (re/reg-event-fx @@ -195,18 +241,11 @@ :args [employer [(clj->js offered-value)] arbiters ipfs-hash] :tx-opts tx-opts :tx-hash [::tx-hash] - :on-tx-receipt [::create-job-tx-receipt] :on-tx-hash-error [::tx-hash-error] :on-tx-success [::create-job-tx-success] :on-tx-error [::create-job-tx-error]}]]]}))) -(re/reg-event-fx - ::create-job-tx-receipt - (fn [_cofx result] - (println ">>> ::create-job-tx-receipt" result))) - - (re/reg-event-fx ::tx-hash-error (fn [{:keys [db]} result] @@ -318,41 +357,6 @@ :fx [[:dispatch safe-transfer-with-create-job-tx]]}))) -(re/reg-event-fx - ::job-to-ipfs-success - (fn [cofx event] - (let [creator (accounts-queries/active-account (:db cofx)) - job-fields (get-in cofx [:db state-key]) - token-type (:job/token-type job-fields) - token-amount (if (= token-type :erc721) - 1 - (get-in job-fields [:job/token-amount :token-amount])) - address-placeholder "0x0000000000000000000000000000000000000000" - token-address (if (not (= token-type :eth)) - (:job/token-address job-fields) - address-placeholder) - offered-value {:value (str token-amount) - :token - {:tokenId (:job/token-id job-fields) - :tokenContract - {:tokenType (contract-constants/token-type->enum-val token-type) - :tokenAddress token-address}}} - invited-arbiters (if (:job/with-arbiter? job-fields) - (into [] (:job/invited-arbiters job-fields)) - []) - new-job-params {:offered-value offered-value - :token-type token-type - :employer creator - :arbiters invited-arbiters - :ipfs-hash (base58->hex (get-in event [1 :Hash]))} - next-event {:eth ::send-create-job-tx - :erc20 ::ensure-erc20-allowance - :erc721 ::safe-transfer-with-create-job - :erc1155 ::safe-transfer-with-create-job}] - {:db (assoc-in (:db cofx) new-job-params-path new-job-params) - :fx [[:dispatch [(get next-event token-type)]]]}))) - - (re/reg-event-fx ::tx-hash (fn [_db event] (println ">>> ethlance.ui.page.new-job.events :tx-hash" event))) @@ -364,29 +368,33 @@ (.then ,,, callback))) +(defn redirect-from-job-created-tx-receipt [web3 transaction-hash] + (w3n-eth/get-transaction-receipt web3 transaction-hash + (fn [err receipt] + (let [job-created (util.tokens/parse-event-in-tx-receipt :JobCreated receipt)] + (println "redirect-from-job-created-tx-receipt" {:err err :receipt receipt :parsed job-created :type (type job-created)}) + (re/dispatch + [::router-events/navigate + :route.job/detail + {:id (:job (first job-created))}]))))) + (re/reg-event-fx ::create-job-tx-success (fn [{:keys [db]} [_event-name tx-data]] - (let [job-from-event (get-in tx-data [:events :Job-created :return-values :job])] - (println ">>> ::create-job-tx-success" tx-data) + (let [job-from-event (get-in tx-data [:events :Job-created :return-values :job]) + parsed-event (util.tokens/parse-event-in-tx-receipt :JobCreated tx-data)] + (println ">>> ::create-job-tx-success tx-data:" tx-data) + (println ">>> ::create-job-tx-success job-from-event:" job-from-event) + (println ">>> ::create-job-tx-success parsed-event:" parsed-event) {:db (set-tx-in-progress db false) :fx [[:dispatch [::notification.events/show "Transaction to create job processed successfully"]] ;; When creating job via ERC721/1155 callback (onERC{721,1155}Received), the event data is part of the ;; tx-receipt, but doesn't have event name, making it difficult to find and decode. Thus this workaround: - ;; - requesting the JobCreated event directly from Ethlance and receiving it correctly decoded + ;; - requesting the transaction receipt (that then has JobCreated event), decoding it and getting the + ;; created job address from there (if job-from-event [:dispatch-later [{:ms 1000 :dispatch [::router-events/navigate :route.job/detail {:id (get-in tx-data [:events :Job-created :return-values :job])}]}]] - (async-request-event {:event "allEvents" - :block-number (:block-number tx-data) - :contract (district.ui.smart-contracts.queries/instance db :ethlance) - :callback (fn [result] - ;; Delaying navigation to give server time to process the contract event - (js/setTimeout - #(re/dispatch - [::router-events/navigate - :route.job/detail - {:id (get (js-obj->clj-map (.-returnValues (first result))) "job")}]) - 1000))}))]}))) + (redirect-from-job-created-tx-receipt (web3-queries/web3 db) (:transaction-hash tx-data)))]}))) (re/reg-event-db @@ -395,10 +403,3 @@ (println ">>> ethlance.ui.page.new-job.events ::create-job-tx-error" event) {:db (set-tx-in-progress db false) :dispatch [::notification.events/show "Error with creating new job transaction"]})) - - -(re/reg-event-fx - ::job-to-ipfs-failure - (fn [{:keys [db]} _] - {:db (set-tx-in-progress db false) - :dispatch [::notification.events/show "Error with loading new job data to IPFS"]})) diff --git a/ui/src/ethlance/ui/page/profile.cljs b/ui/src/ethlance/ui/page/profile.cljs index 1dff30b7..c6c5a3fb 100644 --- a/ui/src/ethlance/ui/page/profile.cljs +++ b/ui/src/ethlance/ui/page/profile.cljs @@ -193,7 +193,8 @@ :placeholder "Briefly describe to what and why you're inviting the candidate" :on-change #(re/dispatch [:page.profile/set-invitation-text %])}] [c-button {:color :primary - :disabled? job-story-exists? + :style {:margin-top "1em"} + :active? (not job-story-exists?) :on-click (fn [] (when-not job-story-exists? (re/dispatch [:page.profile/invite-candidate @@ -226,7 +227,8 @@ {:rating (:feedback/rating item) :text (:feedback/text item) :image-url (-> item :feedback/from-user :user/profile-image) - :author (get-in item [:feedback/from-user :user/name])}) + :author (get-in item [:feedback/from-user :user/name]) + :link-params (navigation/link-params {:route :route.user/profile :params {:address (get-in item [:feedback/from-user :user/id])}})}) (defn c-missing-profile-notification @@ -265,7 +267,8 @@ :feedback/text :feedback/rating [:feedback/from-user - [:user/name + [:user/id + :user/name :user/profile-image]]]]]]]] results (re/subscribe [::gql/query {:queries [query]}]) name (get-in @results [:candidate :user :user/name]) @@ -317,7 +320,8 @@ :feedback/text :feedback/rating [:feedback/from-user - [:user/name + [:user/id + :user/name :user/profile-image]]]]]]]] results (re/subscribe [::gql/query {:queries [query]}]) name (get-in @results [:employer :user :user/name]) @@ -392,7 +396,8 @@ :placeholder "Briefly describe to what and why you're inviting the arbiter" :on-change #(re/dispatch [:page.profile/set-invitation-text %])}] [c-button {:color :primary - :disabled? job-story-exists? + :style {:margin-top "1em"} + :active? (not job-story-exists?) :on-click (fn [] (when-not job-story-exists? (re/dispatch [:page.profile/invite-arbiter @@ -427,7 +432,8 @@ :feedback/text :feedback/rating [:feedback/from-user - [:user/name + [:user/id + :user/name :user/profile-image]]]]]]]] results (re/subscribe [::gql/query {:queries [query]}]) name (get-in @results [:arbiter :user :user/name]) diff --git a/ui/src/ethlance/ui/util/content_helpers.cljs b/ui/src/ethlance/ui/util/content_helpers.cljs new file mode 100644 index 00000000..4159bfb3 --- /dev/null +++ b/ui/src/ethlance/ui/util/content_helpers.cljs @@ -0,0 +1,15 @@ +(ns ethlance.ui.util.content-helpers + (:require + [clojure.string])) + +(defn str->paragraphs [s] + (clojure.string/split-lines s)) + +(defn page-with-title [title content-str] + [:div + [:h2 {:class :title} title] + (into [:div {:class :description :style {:white-space "pre-wrap"}}] + (->> content-str + str->paragraphs + (map clojure.string/trim ,,,) + (map #(conj [:p] %) ,,,)))]) diff --git a/ui/src/ethlance/ui/util/tokens.cljs b/ui/src/ethlance/ui/util/tokens.cljs index 04c0dcb5..fb6907dd 100644 --- a/ui/src/ethlance/ui/util/tokens.cljs +++ b/ui/src/ethlance/ui/util/tokens.cljs @@ -1,10 +1,14 @@ (ns ethlance.ui.util.tokens (:require + [cljs.core.async :as async] [cljs-web3-next.eth :as w3-eth] [cljs-web3-next.helpers :as web3-helpers] [clojure.math] [clojure.walk] - [ethlance.shared.utils :refer [wei->eth eth->wei]])) + [district.ui.smart-contracts.queries] + [district.ui.web3.queries :as web3-queries] + [ethlance.shared.utils :refer [wei->eth eth->wei]] + [re-frame.db :refer [app-db]])) (defn round @@ -66,3 +70,20 @@ remove-unnecessary-keys web3-helpers/js->cljkk clojure.walk/keywordize-keys))) + + +(defn parse-event-in-tx-receipt [event receipt] + (let [getter-fn identity + {:keys [:logs]} (web3-helpers/js->cljkk receipt) + contract-instance (district.ui.smart-contracts.queries/instance @app-db :ethlance) + {:keys [:signature] :as event-interface} (web3-helpers/event-interface contract-instance event) + sought-event? (fn [{:keys [:topics]}] (= signature (first topics))) + web3 (web3-queries/web3 @app-db) + decode-event-data (fn [{:keys [:data :topics]}] (w3-eth/decode-log web3 (:inputs event-interface) data (drop 1 topics))) + clojurize (fn [return-values] (web3-helpers/return-values->clj return-values event-interface))] + (println "parse-event-in-tx-receipt" {:logs logs :signature signature}) + (->> logs + (filter sought-event? ,,,) + (map decode-event-data ,,,) + (map clojurize ,,,) + getter-fn ,,,))) diff --git a/ui/yarn.lock b/ui/yarn.lock index 7f485925..7f65fd4e 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -3383,10 +3383,10 @@ shadow-cljs-jar@1.3.4: resolved "https://registry.yarnpkg.com/shadow-cljs-jar/-/shadow-cljs-jar-1.3.4.tgz#0939d91c468b4bc5eab5a958f79e7ef5696fdf62" integrity sha512-cZB2pzVXBnhpJ6PQdsjO+j/MksR28mv4QD/hP/2y1fsIa9Z9RutYgh3N34FZ8Ktl4puAXaIGlct+gMCJ5BmwmA== -shadow-cljs@2.26.2: - version "2.26.2" - resolved "https://registry.yarnpkg.com/shadow-cljs/-/shadow-cljs-2.26.2.tgz#c9d443940d679c33696009598b01e02a176f6a67" - integrity sha512-xBJxBxSpfoVQLSDA+WN+ZgtnyA5qYf3EE4ARZpov0JOz0YBTdIQajnNYMs5+5OzCbbNfhWGLybyu/Pj4dIwsWw== +shadow-cljs@2.28.16: + version "2.28.16" + resolved "https://registry.yarnpkg.com/shadow-cljs/-/shadow-cljs-2.28.16.tgz#0f705970530cc888ef246cbab87a3d07155328ef" + integrity sha512-6b4V287V0MeZUG+yUxnfCfuVCG1F4sVtpB+KcoDKtZSJIrAjBb1vkZTx/DFct0gYb0WYD5VAPVTzoGy7H+lMFg== dependencies: node-libs-browser "^2.2.1" readline-sync "^1.4.7"