From 24dc8653a6f424df142356182b6a88a4a85c4507 Mon Sep 17 00:00:00 2001 From: ginesdt Date: Thu, 24 Jul 2025 11:00:30 +0200 Subject: [PATCH] add data to ipfs through server --- .../ethlance/server/graphql/resolvers.cljs | 29 ++++++++++++++++++- .../src/ethlance/server/graphql/server.cljs | 2 +- .../src/ethlance/shared/graphql/schema.cljs | 1 + ui/src/ethlance/ui/effects.cljs | 11 +++++++ ui/src/ethlance/ui/events.cljs | 5 ++++ ui/src/ethlance/ui/page/invoices/events.cljs | 7 ++--- .../ethlance/ui/page/job_contract/events.cljs | 21 ++++++-------- .../ethlance/ui/page/job_detail/events.cljs | 7 ++--- .../ethlance/ui/page/new_invoice/events.cljs | 9 +++--- ui/src/ethlance/ui/page/new_job/events.cljs | 7 ++--- ui/src/ethlance/ui/page/profile/events.cljs | 7 ++--- ui/src/ethlance/ui/page/sign_up/events.cljs | 7 ++--- 12 files changed, 74 insertions(+), 39 deletions(-) diff --git a/server/src/ethlance/server/graphql/resolvers.cljs b/server/src/ethlance/server/graphql/resolvers.cljs index 3072ff65..6e093709 100644 --- a/server/src/ethlance/server/graphql/resolvers.cljs +++ b/server/src/ethlance/server/graphql/resolvers.cljs @@ -1,6 +1,7 @@ (ns ethlance.server.graphql.resolvers (:require [camel-snake-kebab.core] + [cljs-ipfs-api.files :as ipfs-files] [clojure.string :as string] [district.graphql-utils :as graphql-utils] [district.server.async-db :as db :include-macros true] @@ -9,6 +10,7 @@ [ethlance.server.db :as ethlance-db] [ethlance.server.event-replay-queue :as replay-queue] [ethlance.server.graphql.authorization :as authorization] + [ethlance.server.ipfs :as ipfs] [ethlance.server.syncer :as syncer] [ethlance.shared.spec :refer [validate-keys]] [honeysql.core :as sql] @@ -1261,6 +1263,30 @@ user))) +(defn data-to-buffer [data] + (let [matcher (re-matches #"data:(\w+/\w+);base64,(.+)" data)] + (if matcher + (let [base64-image (get matcher 2)] + (js/Buffer.from base64-image "base64")) + (ipfs/to-buffer data)))) + + +(defn upload-data-mutation + [_ {:keys [data]} _] + (js/Promise. + (fn [resolve reject] + (ipfs-files/add (data-to-buffer data) + (fn [error result] + (if (or error (empty? result)) + (let [err-txt "Error when adding data to ipfs"] + (log/error err-txt {:result result + :error error + :data data} + :upload-data-mutation) + (println ">>> upload-data-mutation REJECT") + (reject err-txt)) + (resolve (:Hash result)))))))) + (defn replay-events [_ _ _] (db/with-async-resolver-tx conn @@ -1363,6 +1389,7 @@ :removeJobProposal (require-auth remove-job-proposal-mutation) :replayEvents replay-events :githubSignUp (require-auth github-signup-mutation) - :linkedinSignUp (require-auth linkedin-signup-mutation)} + :linkedinSignUp (require-auth linkedin-signup-mutation) + :uploadData (require-auth upload-data-mutation)} ;; :Date ; TODO: https://www.apollographql.com/docs/apollo-server/schema/custom-scalars/#example-the-date-scalar }) diff --git a/server/src/ethlance/server/graphql/server.cljs b/server/src/ethlance/server/graphql/server.cljs index b31781cc..caf4d0fd 100644 --- a/server/src/ethlance/server/graphql/server.cljs +++ b/server/src/ethlance/server/graphql/server.cljs @@ -45,7 +45,7 @@ ;; NOTE: the order off how we are applying middlewares matter app (doto (express) - (.use (.json body-parser)) + (.use (.json body-parser #js {:limit "2mb"})) (.use middlewares/current-user-express-middleware)) server (new ApolloServer diff --git a/shared/src/ethlance/shared/graphql/schema.cljs b/shared/src/ethlance/shared/graphql/schema.cljs index 212cedb9..0104cac4 100644 --- a/shared/src/ethlance/shared/graphql/schema.cljs +++ b/shared/src/ethlance/shared/graphql/schema.cljs @@ -194,6 +194,7 @@ replayEvents: Boolean!, githubSignUp(input: githubSignUpInput!): githubSignUpPayload! linkedinSignUp(input: linkedinSignUpInput!): linkedinSignUpPayload! + uploadData(data: String!): ID! } # mutation result types diff --git a/ui/src/ethlance/ui/effects.cljs b/ui/src/ethlance/ui/effects.cljs index d73e8c08..c8248f63 100644 --- a/ui/src/ethlance/ui/effects.cljs +++ b/ui/src/ethlance/ui/effects.cljs @@ -1,6 +1,8 @@ (ns ethlance.ui.effects (:require [cljs-web3.core :as web3] + [district.ui.graphql.events :as gql-events] + [ethlance.ui.events] [re-frame.core :as re])) @@ -16,3 +18,12 @@ (if err (re/dispatch (conj on-error err)) (re/dispatch (conj on-success (aget result "result")))))))) + + +(re/reg-fx + :data/upload + (fn [{:keys [:data :on-success :on-error]}] + (re/dispatch [::gql-events/mutation + {:queries [[:upload-data {:data (if (string? data) data (pr-str data))}]] + :on-success [:ethlance/data-upload-success on-success] + :on-error on-error}]))) diff --git a/ui/src/ethlance/ui/events.cljs b/ui/src/ethlance/ui/events.cljs index 0113866e..ed7cd079 100644 --- a/ui/src/ethlance/ui/events.cljs +++ b/ui/src/ethlance/ui/events.cljs @@ -57,3 +57,8 @@ [:page.invoices/initialize-page] [:page.new-invoice/initialize-page]] :dispatch-later [{:ms 1000 :dispatch [::listen-account-changes]}]}))) + +(re/reg-event-fx + :ethlance/data-upload-success + (fn [_ [_ on-success result]] + {:dispatch (conj on-success {:Hash (:upload-data result)})})) diff --git a/ui/src/ethlance/ui/page/invoices/events.cljs b/ui/src/ethlance/ui/page/invoices/events.cljs index 4c50f106..8dd8d2a7 100644 --- a/ui/src/ethlance/ui/page/invoices/events.cljs +++ b/ui/src/ethlance/ui/page/invoices/events.cljs @@ -32,10 +32,9 @@ (re/reg-event-fx :page.invoices/pay (fn [_ [_ invoice]] - {:ipfs/call {:func "add" - :args [(js/Blob. [invoice])] - :on-success [::invoice-to-ipfs-success invoice] - :on-error [::invoice-to-ipfs-failure invoice]}})) + {:data/upload {:data invoice + :on-success [::invoice-to-ipfs-success invoice] + :on-error [::invoice-to-ipfs-failure invoice]}})) (re/reg-event-fx diff --git a/ui/src/ethlance/ui/page/job_contract/events.cljs b/ui/src/ethlance/ui/page/job_contract/events.cljs index f823a5c8..417a97a8 100644 --- a/ui/src/ethlance/ui/page/job_contract/events.cljs +++ b/ui/src/ethlance/ui/page/job_contract/events.cljs @@ -144,10 +144,9 @@ :job-story/id job-story-id :invoice/id invoice-id}] {:fx [[:dispatch [::set-buttons-disabled true]]] - :ipfs/call {:func "add" - :args [(js/Blob. [ipfs-dispute])] - :on-success [:page.job-contract/raise-dispute-to-ipfs-success ipfs-dispute] - :on-error [::dispute-to-ipfs-failure invoice-id]}})) + :data/upload {:data ipfs-dispute + :on-success [:page.job-contract/raise-dispute-to-ipfs-success ipfs-dispute] + :on-error [::dispute-to-ipfs-failure invoice-id]}})) (re/reg-event-fx @@ -186,10 +185,9 @@ :message/creator (:employer proposal-data) :text (:text proposal-data)}] {:fx [[:dispatch [::set-buttons-disabled true]]] - :ipfs/call {:func "add" - :args [(js/Blob. [to-ipfs])] - :on-success [:accept-proposal-to-ipfs-success to-ipfs] - :on-error [::accept-proposal-to-ipfs-failure to-ipfs]}}))) + :data/upload {:data to-ipfs + :on-success [:accept-proposal-to-ipfs-success to-ipfs] + :on-error [::accept-proposal-to-ipfs-failure to-ipfs]}}))) (re/reg-event-fx @@ -273,10 +271,9 @@ :job/id job-id :job-story/id job-story-id :invoice/id invoice-id}] - {:ipfs/call {:func "add" - :args [(js/Blob. [ipfs-dispute])] - :on-success [:page.job-contract/resolve-dispute-to-ipfs-success event] - :on-error [::dispute-to-ipfs-failure event]}})) + {:data/upload {:data ipfs-dispute + :on-success [:page.job-contract/resolve-dispute-to-ipfs-success event] + :on-error [::dispute-to-ipfs-failure event]}})) (defn send-resolve-dispute-tx diff --git a/ui/src/ethlance/ui/page/job_detail/events.cljs b/ui/src/ethlance/ui/page/job_detail/events.cljs index a73e499b..67ffe37c 100644 --- a/ui/src/ethlance/ui/page/job_detail/events.cljs +++ b/ui/src/ethlance/ui/page/job_detail/events.cljs @@ -216,10 +216,9 @@ :job-arbiter/fee :job-arbiter/fee-currency-id])] {:fx [[:dispatch [::set-arbiter-tx-in-progress true]]] - :ipfs/call {:func "add" - :args [(js/Blob. [ipfs-arbitration])] - :on-success [:page.job-detail/arbitration-to-ipfs-success event] - :on-error [::arbitration-to-ipfs-failed]}})) + :data/upload {:data ipfs-arbitration + :on-success [:page.job-detail/arbitration-to-ipfs-success event] + :on-error [::arbitration-to-ipfs-failed]}})) (re/reg-event-fx diff --git a/ui/src/ethlance/ui/page/new_invoice/events.cljs b/ui/src/ethlance/ui/page/new_invoice/events.cljs index 83bced78..4e3c866f 100644 --- a/ui/src/ethlance/ui/page/new_invoice/events.cljs +++ b/ui/src/ethlance/ui/page/new_invoice/events.cljs @@ -102,11 +102,10 @@ :message/text (:message db-invoice) :job/id (-> db-invoice :invoiced-job :job/id) :job-story/id (-> db-invoice :invoiced-job :job-story/id parse-int)}] - {:fx [[:dispatch [::set-tx-in-progress true]] - [:ipfs/call {:func "add" - :args [(js/Blob. [ipfs-invoice])] - :on-success [::invoice-to-ipfs-success ipfs-invoice] - :on-error [::invoice-to-ipfs-failure ipfs-invoice]}]]}))) + {:fx [[:dispatch [::set-tx-in-progress true]]] + :data/upload {:data ipfs-invoice + :on-success [::invoice-to-ipfs-success ipfs-invoice] + :on-error [::invoice-to-ipfs-failure ipfs-invoice]}}))) (re/reg-event-fx diff --git a/ui/src/ethlance/ui/page/new_job/events.cljs b/ui/src/ethlance/ui/page/new_job/events.cljs index 35bb683b..cf9125cb 100644 --- a/ui/src/ethlance/ui/page/new_job/events.cljs +++ b/ui/src/ethlance/ui/page/new_job/events.cljs @@ -206,10 +206,9 @@ (fn [{:keys [db]}] (let [db-job (get db state-key) ipfs-job (reduce-kv (partial db-job->ipfs-job db-job) {} db->ipfs-mapping)] - {:fx [[:ipfs/call {:func "add" - :args [(js/Blob. [ipfs-job])] - :on-success [::job-to-ipfs-success] - :on-error [::job-to-ipfs-failure]}]]}))) + {:data/upload {:data ipfs-job + :on-success [::job-to-ipfs-success] + :on-error [::job-to-ipfs-failure]}}))) (re/reg-event-fx diff --git a/ui/src/ethlance/ui/page/profile/events.cljs b/ui/src/ethlance/ui/page/profile/events.cljs index 0aed27d7..06534ff7 100644 --- a/ui/src/ethlance/ui/page/profile/events.cljs +++ b/ui/src/ethlance/ui/page/profile/events.cljs @@ -55,10 +55,9 @@ :job/id (get-in invitation-data [:job :job/id]) :message/creator (:employer invitation-data) :text (:text invitation-data)}] - {:ipfs/call {:func "add" - :args [(js/Blob. [ipfs-invitation])] - :on-success [:invitation-to-ipfs-success ipfs-invitation] - :on-error [:invitation-to-ipfs-failure ipfs-invitation]}}))) + {:data/upload {:data ipfs-invitation + :on-success [:invitation-to-ipfs-success ipfs-invitation] + :on-error [:invitation-to-ipfs-failure ipfs-invitation]}}))) (re/reg-event-fx diff --git a/ui/src/ethlance/ui/page/sign_up/events.cljs b/ui/src/ethlance/ui/page/sign_up/events.cljs index 9ea77140..044baf89 100644 --- a/ui/src/ethlance/ui/page/sign_up/events.cljs +++ b/ui/src/ethlance/ui/page/sign_up/events.cljs @@ -161,10 +161,9 @@ :page.sign-up/upload-user-image [interceptors] (fn [_ [{:keys [:file-info] :as data}]] - {:ipfs/call {:func "add" - :args [(:file file-info)] - :on-success [::upload-user-image-success data] - :on-error [::logging/error "Error uploading user image" {:data data}]}})) + {:data/upload {:data (-> file-info :selected-file :url-data) + :on-success [::upload-user-image-success data] + :on-error [::logging/error "Error uploading user image" {:data data}]}})) (re/reg-event-fx