diff --git a/app/components/sidebar/index.tsx b/app/components/sidebar/index.tsx index 771d8e4..73b038c 100644 --- a/app/components/sidebar/index.tsx +++ b/app/components/sidebar/index.tsx @@ -19,7 +19,7 @@ export function Sidebar({ auth }: { auth: AuthData }) { const fetcher = useFetcher(); const { isOpen, onOpen, onClose } = useDisclosure(); - const logoutHandler = () => { + const logoutHandler = () => { fetcher.submit(null, { method: "post", action: `/logout/action`, diff --git a/app/entry.server.tsx b/app/entry.server.tsx index 881dfe9..ba19cee 100644 --- a/app/entry.server.tsx +++ b/app/entry.server.tsx @@ -3,7 +3,7 @@ import { renderToString } from "react-dom/server"; import { CacheProvider } from "@emotion/react"; import createEmotionServer from "@emotion/server/create-instance"; import { RemixServer } from "@remix-run/react"; -import type { EntryContext } from "@remix-run/node"; // Depends on the runtime you choose +import { type EntryContext } from "@remix-run/node"; // Depends on the runtime you choose import { ServerStyleContext } from "./context"; import createEmotionCache from "./createEmotionCache"; diff --git a/app/errors/base.tsx b/app/errors/base.tsx index 3e24ebb..d3995cd 100644 --- a/app/errors/base.tsx +++ b/app/errors/base.tsx @@ -1,11 +1,25 @@ -import { useRouteError, isRouteErrorResponse } from "@remix-run/react"; +import { useRouteError, isRouteErrorResponse, useNavigate, useFetcher } from "@remix-run/react"; +import { useEffect } from "react"; export const BaseError = () => { - const error = useRouteError(); + const error: any = useRouteError(); + const navigate = useNavigate(); + const fetcher = useFetcher(); + + useEffect(() => { + if (typeof error.message === "string" && error.message.includes("401")) { + // redirect to logout action + fetcher.submit(null, { + method: "post", + action: `/logout/action`, + }); + } + }, [error, navigate]); + if (isRouteErrorResponse(error)) { console.log(`App Error(isRouteErrorResponse) = ${error}`); } else { - console.log(`App Error = ${error}`); + console.log(`App sssError = ${error}`); } return <>here in error section; diff --git a/app/middlewares/with-auth.ts b/app/middlewares/with-auth.ts index 0b6c08b..f6612af 100644 --- a/app/middlewares/with-auth.ts +++ b/app/middlewares/with-auth.ts @@ -22,7 +22,7 @@ export function withAuth(fn: LoaderFunction): LoaderFunction { const excludedRoutes = ["/login", "/signup"]; const { url } = args.request const isExcludedRoute = excludedRoutes.some(route => url.includes(route)); - + // return to login if dont have valid auth info if (!data?.token && !isExcludedRoute) { return redirect("/login"); diff --git a/app/models/backoffice/backoffice-cookie.server.ts b/app/models/backoffice/backoffice-cookie.server.ts index 77ad1ae..a0df4d4 100644 --- a/app/models/backoffice/backoffice-cookie.server.ts +++ b/app/models/backoffice/backoffice-cookie.server.ts @@ -1,14 +1,12 @@ import invariant from "tiny-invariant"; -import { createFileSessionStorage, createCookie } from "@remix-run/node"; +import { createCookieSessionStorage } from "@remix-run/node"; -const { COOKIE_SECRET} = process.env; +const { COOKIE_SECRET } = process.env; invariant(typeof COOKIE_SECRET === "string", "COOKIE_SECRET env var not set"); -const backofficeSession = createCookie("backofficeSession", { - secrets: [COOKIE_SECRET!] -}); - -export const { getSession, commitSession, destroySession } = createFileSessionStorage({ - dir: "./sessions", - cookie: backofficeSession, -}); +export const { getSession, commitSession, destroySession } = createCookieSessionStorage({ + cookie: { + name: "backofficeSession", + secrets: [COOKIE_SECRET!] + }, +}); \ No newline at end of file diff --git a/app/models/jobs/create-job-cookie.server.ts b/app/models/darchlabs/create-job-cookie.server.ts similarity index 100% rename from app/models/jobs/create-job-cookie.server.ts rename to app/models/darchlabs/create-job-cookie.server.ts diff --git a/app/models/synchronizers/create-synchronizers-cookie.server.ts b/app/models/darchlabs/create-synchronizers-cookie.server.ts similarity index 100% rename from app/models/synchronizers/create-synchronizers-cookie.server.ts rename to app/models/darchlabs/create-synchronizers-cookie.server.ts diff --git a/app/models/jobs.server.ts b/app/models/jobs.server.ts deleted file mode 100644 index 7851b8a..0000000 --- a/app/models/jobs.server.ts +++ /dev/null @@ -1,31 +0,0 @@ -import Job from "./jobs"; -import invariant from "tiny-invariant"; - -// TODO(nb): Make this file only getting the env values from `.env.jobs`?/ -// Or it should get from `.env`? - -let job: Job; - -declare global { - var __jobs__: Job; -} - -if (process.env.NODE_ENV === "production") { - job = getClient(); -} else { - if (!global.__jobs__) { - global.__jobs__ = getClient(); - } - job = global.__jobs__; -} - -function getClient() { - const { JOB_API_URL } = process.env; - invariant(typeof JOB_API_URL === "string", "JOB_API_URL env var not set"); - - const client = new Job(JOB_API_URL); - - return client; -} - -export { job }; diff --git a/app/models/jobs/index.ts b/app/models/jobs/index.ts deleted file mode 100644 index 2f387fe..0000000 --- a/app/models/jobs/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Is an alias of Jobs -import JobsClient from "./jobs"; - -export default JobsClient; diff --git a/app/models/jobs/jobs.ts b/app/models/jobs/jobs.ts deleted file mode 100644 index 87ed1b3..0000000 --- a/app/models/jobs/jobs.ts +++ /dev/null @@ -1,114 +0,0 @@ -import fetch from "@remix-run/web-fetch"; -import type { ListProvidersResponse, ListJobsResponse, CreateJobResponse, HTTPResponse } from "./requests"; -import type { JobInput } from "./types"; - -export default class Jobs { - private URL: string; - - constructor(URL: string) { - this.URL = URL; - } - - public async ListJobs(): Promise { - try { - const url = `${this.URL}/api/v1/jobs`; - const res = await fetch(url, { - method: "GET", - headers: { - "content-type": "application/json", - }, - }); - - const data = (await res.json()) as ListJobsResponse; - return data; - } catch (err: any) { - throw err; - } - } - - public async ListProviders(): Promise { - try { - const url = `${this.URL}/api/v1/jobs/providers`; - const res = await fetch(url, { - method: "GET", - headers: { - "content-type": "application/json", - }, - }); - - const data = (await res.json()) as ListProvidersResponse; - return data; - } catch (err: any) { - throw err; - } - } - - public async CreateJob(req: JobInput): Promise { - try { - const url = `${this.URL}/api/v1/jobs`; - const res = await fetch(url, { - method: "POST", - headers: { - "content-type": "application/json", - }, - body: JSON.stringify({ job: req }), - }); - - const data = (await res.json()) as CreateJobResponse; - return data; - } catch (err: any) { - throw err; - } - } - - public async DeleteJob(id: string): Promise { - try { - const url = `${this.URL}/api/v1/jobs/${id}`; - const res = await fetch(url, { - method: "DELETE", - headers: { - "content-type": "application/json", - }, - }); - - const data = (await res.json()) as HTTPResponse; - return data; - } catch (err: any) { - throw err; - } - } - - public async StartJob(id: string): Promise { - try { - const url = `${this.URL}/api/v1/jobs/${id}/start`; - const res = await fetch(url, { - method: "POST", - headers: { - "content-type": "application/json", - }, - }); - - const data = (await res.json()) as HTTPResponse; - return data; - } catch (err: any) { - throw err; - } - } - - public async StopJob(id: string): Promise { - try { - const url = `${this.URL}/api/v1/jobs/${id}/stop`; - const res = await fetch(url, { - method: "POST", - headers: { - "content-type": "application/json", - }, - }); - - const data = (await res.json()) as HTTPResponse; - return data; - } catch (err: any) { - throw err; - } - } -} diff --git a/app/models/jobs/requests.ts b/app/models/jobs/requests.ts deleted file mode 100644 index 922b8f6..0000000 --- a/app/models/jobs/requests.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { Provider, Job } from "./types"; - -export type ListJobsResponse = { - data: Job[]; - meta: number; -}; - -export type ListProvidersResponse = { - data: Provider[]; - meta: number; -}; - -export type CreateJobResponse = { - data: Job | string; - meta: number; -}; - -export type HTTPResponse = { - meta: number; -}; diff --git a/app/models/jobs/types.ts b/app/models/jobs/types.ts deleted file mode 100644 index b7c325f..0000000 --- a/app/models/jobs/types.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { network } from "darchlabs"; - -export type JobStatus = "idle" | "running" | "stopped" | "autoStopped" | "error"; - -export type Job = { - id: string; - name: string; - providerId: string; - status: JobStatus; - network: network.Network; - address: string; - abi: string; - nodeUrl: string; - privateKey: string; - type: string; - cronjob: string; - checkMethod: string; - actionMethod: string; - // add as time module - createdAt: string; - updatedAt: string; - logs: string[]; -}; - -export type Provider = { - id: string; - name: string; - networks: network.Network[]; -}; - -export type JobsForm = { - providerId: string; - network: network.Network; - address: string; - abi: string; - cronjob: string; - nodeURL: string; - checkMethod: string; - actionMethod: string; - privateKey: string; - raw?: string; -}; - -export type JobsFormData = JobsForm & {}; - -export type JobsRequest = { - name: string; - providerId: string; - network: string; - address: string; - abi: string; - nodeUrl: string; - privateKey: string; - type: string; - cronjob: string; - checkMethod: string; - actionMethod: string; -}; - -export type JobInput = { - name: string; - providerId: string; - network: network.Network; - address: string; - nodeUrl: string; - privateKey: string; - abi: string; - type: "cronjob"; - cronjob: string; - checkMethod: string; - actionMethod: string; -}; diff --git a/app/root.tsx b/app/root.tsx index a931b06..0812fdc 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -1,8 +1,8 @@ import React, { useContext, useEffect } from "react"; import { withEmotionCache } from "@emotion/react"; import { ChakraProvider } from "@chakra-ui/react"; -import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react"; -import type { V2_MetaFunction, LinksFunction } from "@remix-run/node"; // Depends on the runtime you choose +import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration, useLoaderData, useFetcher } from "@remix-run/react"; +import { type V2_MetaFunction, type LinksFunction, type LoaderFunction, redirect, LoaderArgs } from "@remix-run/node"; // Depends on the runtime you choose import { metaV1 } from "@remix-run/v1-meta"; import { ServerStyleContext, ClientStyleContext } from "./context"; @@ -77,11 +77,11 @@ const Document = withEmotionCache(({ children }: DocumentProps, emotionCache) => ); }); -export default function App() { +export default function App() { return ( - + ); diff --git a/app/routes/events.$address.loader.ts b/app/routes/events.$address.loader.ts index 547c485..a0f29a9 100644 --- a/app/routes/events.$address.loader.ts +++ b/app/routes/events.$address.loader.ts @@ -1,10 +1,10 @@ import type { LoaderFunction, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { pagination, synchronizers } from "darchlabs"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; import { redirect } from "react-router-dom"; import { withPagination } from "@middlewares/with-pagination"; import { AuthData, withAuth } from "@middlewares/with-auth"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; export type EventsCounts = { [eventName: string]: number }; @@ -13,9 +13,10 @@ export type EventsLoaderData = { address: string; eventsCounts: EventsCounts; auth: AuthData; + pagination: pagination.Pagination; }; -export const EventsLoader: LoaderFunction = withAuth(withPagination(async ({ params, context }: LoaderArgs) => { +export const EventsLoader: LoaderFunction = withAuth(withPagination(async ({ params, context, request }: LoaderArgs) => { // get address path param const { address } = params; if (!address || address === "") { @@ -23,28 +24,37 @@ export const EventsLoader: LoaderFunction = withAuth(withPagination(async ({ par } // get pagination context for middleware - const pagination = context.pagination as pagination.Pagination | {}; - - // get events - const { events } = await Darchlabs.synchronizers.events.listEventsByAddress(address!, pagination); - if (!events.length) { - return redirect("/synchronizers"); - } - - const eventsCounts: { [eventName: string]: number } = {}; - for (let i = 0; i < events.length; i++) { - const event = events[i]; - const eventName = event?.abi?.name; - const { pagination } = await Darchlabs.synchronizers.events.listEventData(address, eventName, { - page: 0, - limit: 1, - }); - - eventsCounts[eventName] = pagination?.totalElements; + const pagination = context.pagination as pagination.Pagination || {}; + + // get events from darchlabs + let events: synchronizers.Event[]; + let eventsCounts: EventsCounts = {}; + try { + // get darchlabs client + const client = await GetDarchlabsClient(request); + + // get events + ({ events } = await client.synchronizers.events.listEventsByAddress(address!, pagination)); + if (!events.length) { + return redirect("/synchronizers"); + } + + for (let i = 0; i < events.length; i++) { + const event = events[i]; + const eventName = event?.abi?.name; + const { pagination: p } = await client.synchronizers.events.listEventData(address, eventName, { + page: 0, + limit: 1, + }); + + eventsCounts[eventName] = p?.totalElements; + } + } catch (err) { + throw err; } // get auth context from middleware const auth = context.auth as AuthData; - return json({ events, eventsCounts, address, auth }); + return json({ events, eventsCounts, address, auth, pagination }); })); diff --git a/app/routes/events.$address.tsx b/app/routes/events.$address.tsx index a55adb0..55033e0 100644 --- a/app/routes/events.$address.tsx +++ b/app/routes/events.$address.tsx @@ -12,13 +12,11 @@ export const loader: LoaderFunction = EventsLoader; export default function App() { const { - events: { - data, - meta: { pagination }, - }, + events, eventsCounts, address, auth, + pagination, } = useLoaderData(); return ( @@ -30,8 +28,8 @@ export default function App() { emptyMsg={"You do not have any registered event."} pagination={pagination} > - {data.map((item, index) => ( - + {events.map((event, index) => ( + ))} diff --git a/app/routes/jobs.action.ts b/app/routes/jobs.action.ts index 538d35c..5eed4df 100644 --- a/app/routes/jobs.action.ts +++ b/app/routes/jobs.action.ts @@ -1,6 +1,6 @@ import type { ActionFunction } from "@remix-run/node"; -import { job } from "@models/jobs.server"; import { redirect } from "@remix-run/node"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; type JobActionForm = { action: string; @@ -13,13 +13,20 @@ export const action: ActionFunction = async ({ request }: { request: Request }) const formData = await request.formData(); const { action, redirectURL, id } = Object.fromEntries(formData) as JobActionForm; - // execute action on jobs api - if (action === "start") { - await job.StartJob(id); - } else if (action === "stop") { - await job.StopJob(id); - } else if (action === "delete") { - await job.DeleteJob(id); + try { + // get darchlabs client + const client = await GetDarchlabsClient(request); + + // execute action on jobs api + if (action === "start") { + await client.jobs.startJob(id); + } else if (action === "stop") { + await client.jobs.stopJob(id); + } else if (action === "delete") { + await client.jobs.deleteJob(id); + } + } catch (err) { + throw err } return redirect(redirectURL); diff --git a/app/routes/jobs.create.abi.action.tsx b/app/routes/jobs.create.abi.action.tsx index 7b302a1..1ceb0f8 100644 --- a/app/routes/jobs.create.abi.action.tsx +++ b/app/routes/jobs.create.abi.action.tsx @@ -1,8 +1,8 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; import { z } from "zod"; import { GetAbiSchema } from "@utils/get-abi-schema"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; import { ValidateContractAbi } from "@utils/validate-contract-abi"; type AbiActionForm = { @@ -61,7 +61,7 @@ export const CreateJobAbiAction = async function action({ request }: ActionArgs) // get cookie session const session = await getSession(request.headers.get("Cookie")); - const jobSession: JobInput = session.get("jobSession"); + const jobSession: jobs.JobInput = session.get("jobSession"); if (!jobSession) { return redirect("/jobs/create"); } diff --git a/app/routes/jobs.create.abi.loader.ts b/app/routes/jobs.create.abi.loader.ts index a8d8a01..ae05bf9 100644 --- a/app/routes/jobs.create.abi.loader.ts +++ b/app/routes/jobs.create.abi.loader.ts @@ -1,29 +1,26 @@ import { type Cookie, withCookie } from "@middlewares/with-cookie"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; import { type LoaderArgs, type LoaderFunction, json, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; -import { job } from "@models/jobs.server"; -import { type Provider } from "@models/jobs/types"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; import { GetABI } from "@utils/get-abi"; export type LoaderData = { - job: JobInput; - providers: Provider[]; + job: jobs.JobInput; }; -export const CreateJobAbiLoader: LoaderFunction = withCookie( +export const CreateJobAbiLoader: LoaderFunction = withCookie( "jobSession", getSession, commitSession, async ({ context, request }: LoaderArgs) => { // get job session - let jobSession = context["jobSession"] as Cookie; + let jobSession = context["jobSession"] as Cookie; const { network, address } = jobSession.data // get and save abi from scan try { const session = await getSession(request.headers.get("Cookie")); - const jobSession: JobInput = session.get("jobSession"); + const jobSession: jobs.JobInput = session.get("jobSession"); const abi = await GetABI(network, address); const abiStr = JSON.stringify(abi) session.set("jobSession", { ...jobSession, abi: abiStr }); @@ -33,13 +30,9 @@ export const CreateJobAbiLoader: LoaderFunction = withCookie( console.log(`Warn: ${err.message}`); } - // get provider list - const { data: providers } = await job.ListProviders(); - return json( { job: jobSession.data, - providers, }, { headers: { diff --git a/app/routes/jobs.create.account.action.tsx b/app/routes/jobs.create.account.action.tsx index 04fa32e..d2d7e7d 100644 --- a/app/routes/jobs.create.account.action.tsx +++ b/app/routes/jobs.create.account.action.tsx @@ -1,8 +1,8 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; import { z } from "zod"; import { isHexString } from "ethers"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; import { ValidatePrivateKey } from "@utils/validate-private-key"; type AccountActionForm = { @@ -54,7 +54,7 @@ export const CreateJobAccountAction = async function action({ request }: ActionA // get cookie session const session = await getSession(request.headers.get("Cookie")); - const jobSession: JobInput = session.get("jobSession"); + const jobSession: jobs.JobInput = session.get("jobSession"); if (!jobSession) { return redirect("/jobs/create"); } diff --git a/app/routes/jobs.create.address.action.tsx b/app/routes/jobs.create.address.action.tsx index c0ef572..c25992b 100644 --- a/app/routes/jobs.create.address.action.tsx +++ b/app/routes/jobs.create.address.action.tsx @@ -1,8 +1,8 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; import { z } from "zod"; import { isAddress } from "ethers"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; import { ValidateAddressContractInNetwork } from "@utils/validate-address-contract-in-network"; type AddressActionForm = { @@ -44,7 +44,7 @@ export const CreateJobAddressAction = async function action({ request }: ActionA // get cookie session const session = await getSession(request.headers.get("Cookie")); - const jobSession: JobInput = session.get("jobSession"); + const jobSession: jobs.JobInput = session.get("jobSession"); if (!jobSession) { return redirect("/jobs/create"); } diff --git a/app/routes/jobs.create.confirm.action.tsx b/app/routes/jobs.create.confirm.action.tsx index d62c830..3138e23 100644 --- a/app/routes/jobs.create.confirm.action.tsx +++ b/app/routes/jobs.create.confirm.action.tsx @@ -1,8 +1,8 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, destroySession } from "@models/jobs/create-job-cookie.server"; -import { job } from "@models/jobs.server"; -import { type JobInput } from "@models/jobs/types"; +import { getSession, destroySession } from "@models/darchlabs/create-job-cookie.server"; +import { jobs } from "darchlabs"; import { GetNodeUrlByNetwork } from "@utils/get-nodeurl-by-network"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; type ConfirmActionForm = { baseTo: string; @@ -22,7 +22,7 @@ export const CreateJobConfirmAction = async function action({ request }: ActionA // get cookie session const session = await getSession(request.headers.get("Cookie")); - const jobSession: JobInput = session.get("jobSession"); + const jobSession: jobs.JobInput = session.get("jobSession"); if (!jobSession) { return redirect("/jobs/create"); } @@ -34,18 +34,12 @@ export const CreateJobConfirmAction = async function action({ request }: ActionA return redirect("/jobs/create") } jobSession.nodeUrl = nodeUrl; + jobSession.type = "cronjob"; // create job in api try { - jobSession.type = "cronjob"; - const response = await job.CreateJob(jobSession); - if (response.meta === 400) { - return { - confirm: { - error: response.data, - }, - } as ConfirmActionData; - } + const client = await GetDarchlabsClient(request); + await client.jobs.createJob(jobSession); } catch (err: any) { return { confirm: { diff --git a/app/routes/jobs.create.confirm.loader.ts b/app/routes/jobs.create.confirm.loader.ts index 754f7e8..5f57614 100644 --- a/app/routes/jobs.create.confirm.loader.ts +++ b/app/routes/jobs.create.confirm.loader.ts @@ -1,17 +1,15 @@ import { type Cookie, withCookie } from "@middlewares/with-cookie"; import { type LoaderArgs, type LoaderFunction, json, redirect } from "@remix-run/node"; -import { type network } from "darchlabs"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; -import { type JobInput } from "@models/jobs/types"; -import { job } from "@models/jobs.server"; +import { network, jobs } from "darchlabs"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; -export const CreateJobConfirmLoader: LoaderFunction = withCookie( +export const CreateJobConfirmLoader: LoaderFunction = withCookie( "jobSession", getSession, commitSession, async ({ context }: LoaderArgs) => { // get session - const jobSession = context["jobSession"] as Cookie; + const jobSession = context["jobSession"] as Cookie; // define options to use in json or in redirect const opts = { @@ -62,12 +60,9 @@ export const CreateJobConfirmLoader: LoaderFunction = withCookie( return redirect("/jobs/create/account", opts); } - const { data } = await job.ListProviders(); - return json( { job: jobSession.data, - providers: data, }, { headers: { diff --git a/app/routes/jobs.create.cronjob.action.tsx b/app/routes/jobs.create.cronjob.action.tsx index f6c8963..a67c172 100644 --- a/app/routes/jobs.create.cronjob.action.tsx +++ b/app/routes/jobs.create.cronjob.action.tsx @@ -1,8 +1,8 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; import { z } from "zod"; import cron from "cron-validate"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; type CronjobActionForm = { baseTo: string; @@ -55,7 +55,7 @@ export const CreateJobCronjobAction = async function action({ request }: ActionA // get cookie session const session = await getSession(request.headers.get("Cookie")); - const jobSession: JobInput = session.get("jobSession"); + const jobSession: jobs.JobInput = session.get("jobSession"); if (!jobSession) { return redirect("/jobs/create"); } diff --git a/app/routes/jobs.create.loader.ts b/app/routes/jobs.create.loader.ts index ee9f8f4..f9d92fe 100644 --- a/app/routes/jobs.create.loader.ts +++ b/app/routes/jobs.create.loader.ts @@ -1,19 +1,19 @@ import { type Cookie, withCookie } from "@middlewares/with-cookie"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; import { type LoaderArgs, type LoaderFunction, json } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; export type LoaderData = { - job: JobInput; + job: jobs.JobInput; }; -export const CreateJobLoader: LoaderFunction = withCookie( +export const CreateJobLoader: LoaderFunction = withCookie( "jobSession", getSession, commitSession, async ({ context }: LoaderArgs) => { // get job session - const jobSession = context["jobSession"] as Cookie; + const jobSession = context["jobSession"] as Cookie; return json( { diff --git a/app/routes/jobs.create.methods.action.tsx b/app/routes/jobs.create.methods.action.tsx index 404c313..f7cda39 100644 --- a/app/routes/jobs.create.methods.action.tsx +++ b/app/routes/jobs.create.methods.action.tsx @@ -1,7 +1,7 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; import { z } from "zod"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; type MethodsActionForm = { baseTo: string; @@ -52,7 +52,7 @@ export const CreateJobMethodsAction = async function action({ request }: ActionA // get cookie session const session = await getSession(request.headers.get("Cookie")); - const jobSession: JobInput = session.get("jobSession"); + const jobSession: jobs.JobInput = session.get("jobSession"); if (!jobSession) { return redirect("/jobs/create"); } diff --git a/app/routes/jobs.create.name.action.tsx b/app/routes/jobs.create.name.action.tsx index c8719d2..8945488 100644 --- a/app/routes/jobs.create.name.action.tsx +++ b/app/routes/jobs.create.name.action.tsx @@ -1,7 +1,7 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; import { z } from "zod"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; type NameActionForm = { baseTo: string; @@ -42,7 +42,7 @@ export const CreateJobNameAction = async function action({ request }: ActionArgs // get cookie session const session = await getSession(request.headers.get("Cookie")); - const jobSession: JobInput = session.get("jobSession"); + const jobSession: jobs.JobInput = session.get("jobSession"); if (!jobSession) { return redirect("/jobs/create"); } diff --git a/app/routes/jobs.create.network.action.tsx b/app/routes/jobs.create.network.action.tsx index 3526d15..33ea5e9 100644 --- a/app/routes/jobs.create.network.action.tsx +++ b/app/routes/jobs.create.network.action.tsx @@ -1,8 +1,8 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; import { network } from "darchlabs"; import { z } from "zod"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; type NetworkActionForm = { baseTo: string; @@ -45,7 +45,7 @@ export const CreateJobNetworkAction = async function action({ request }: ActionA // upsert to create cookie const session = await getSession(request.headers.get("Cookie")); - const scInput: JobInput = session.get("jobSession"); + const scInput: jobs.JobInput = session.get("jobSession"); // set nework value in cookie scInput.network = form.network; diff --git a/app/routes/jobs.create.network.tsx b/app/routes/jobs.create.network.tsx index 2ec6f7f..bf18308 100644 --- a/app/routes/jobs.create.network.tsx +++ b/app/routes/jobs.create.network.tsx @@ -6,7 +6,7 @@ import { Create, TemplateTitleDescriptionHint, NetworkSelectInput } from "@compo import { CreateJobNetworkAction, type NetworkActionData } from "./jobs.create.network.action"; import { CreateJobLoader, type LoaderData } from "./jobs.create.loader"; import { FormTitle, FormName, Steps } from "./jobs.create._index"; -import { JobNetwoks } from "darchlabs"; +import { jobs } from "darchlabs"; export const action: ActionFunction = CreateJobNetworkAction; export const loader: LoaderFunction = CreateJobLoader; @@ -25,7 +25,7 @@ export default function CreateJobNetwork() { nextTo="name" > <> - + <> diff --git a/app/routes/jobs.create.node.action.tsx b/app/routes/jobs.create.node.action.tsx index 45903a9..b5d089e 100644 --- a/app/routes/jobs.create.node.action.tsx +++ b/app/routes/jobs.create.node.action.tsx @@ -1,8 +1,8 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/jobs/create-job-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-job-cookie.server"; import { z } from "zod"; import { ValidateClient } from "@utils/validate-client"; -import { type JobInput } from "@models/jobs/types"; +import { jobs } from "darchlabs"; type NodeActionForm = { baseTo: string; @@ -43,7 +43,7 @@ export const CreateJobsNodeAction = async function action({ request }: ActionArg // get cookie session const session = await getSession(request.headers.get("Cookie")); - const jobSession: JobInput = session.get("jobSession"); + const jobSession: jobs.JobInput = session.get("jobSession"); if (!jobSession) { return redirect("/jobs/create"); } diff --git a/app/routes/jobs.loader.ts b/app/routes/jobs.loader.ts index 071242a..6d594cf 100644 --- a/app/routes/jobs.loader.ts +++ b/app/routes/jobs.loader.ts @@ -1,20 +1,25 @@ import { json, LoaderArgs, type LoaderFunction } from "@remix-run/node"; -import type { Job, Provider } from "@models/jobs/types"; -import { job } from "@models/jobs.server"; +import { jobs } from "darchlabs"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server" import { AuthData, withAuth } from "@middlewares/with-auth"; export type LoaderData = { - jobs: Job[]; - providers: Provider[]; + jobs: jobs.Job[]; auth: AuthData; }; -export const JobsLoader: LoaderFunction = withAuth(async ({ context }: LoaderArgs) => { - const { data: jobsData } = await job.ListJobs(); - const { data: providersData } = await job.ListProviders(); +export const JobsLoader: LoaderFunction = withAuth(async ({ context, request }: LoaderArgs) => { + // get jobs from darchlabs + let jobs: jobs.Job[]; + try { + const client = await GetDarchlabsClient(request); + (jobs = await client.jobs.listJobs()) + } catch (err) { + throw err + } // get auth context from middleware const auth = context.auth as AuthData; - return json({ jobs: jobsData, providers: providersData, auth }); + return json({ jobs, auth }); }); diff --git a/app/routes/jobs.tsx b/app/routes/jobs.tsx index c72df25..453445e 100644 --- a/app/routes/jobs.tsx +++ b/app/routes/jobs.tsx @@ -27,7 +27,7 @@ export default function App() { diff --git a/app/routes/login.action.tsx b/app/routes/login.action.tsx index f7f0708..0f9cde6 100644 --- a/app/routes/login.action.tsx +++ b/app/routes/login.action.tsx @@ -1,9 +1,9 @@ import { type ActionArgs, redirect } from "@remix-run/node"; import { getSession, commitSession } from "@models/backoffice/backoffice-cookie.server"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; import {Backoffice} from "@models/backoffice/backoffice.server" import { AuthData } from "@middlewares/with-auth"; import { z } from 'zod'; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; type LoginActionForm = { email: string; @@ -16,7 +16,7 @@ export type LoginActionData = { error?: string }; -export const LoginAction = async function action({ request, params }: ActionArgs) { +export const LoginAction = async function action({ request }: ActionArgs) { // parse form const formData = await request.formData(); const form = Object.fromEntries(formData) as LoginActionForm; @@ -75,15 +75,12 @@ export const LoginAction = async function action({ request, params }: ActionArgs const session = await getSession(request.headers.get("Cookie")); const data: AuthData = session.get("backofficeSession") || {} as AuthData; data.token = token - data.email = form.email - + data.email = form.email + // set token value in cookie session.set("backofficeSession", data); const cookie = await commitSession(session); - // set token in darchlabs client - Darchlabs.updateApiKey(token) - // redirect return redirect(redirectTo, { headers: { diff --git a/app/routes/login.loader.tsx b/app/routes/login.loader.tsx index 623ce22..c568a3b 100644 --- a/app/routes/login.loader.tsx +++ b/app/routes/login.loader.tsx @@ -2,6 +2,8 @@ import { withAuth } from "@middlewares/with-auth"; import { json, redirect, type LoaderArgs, type LoaderFunction } from "@remix-run/node"; export const LoginLoader: LoaderFunction = withAuth(async ({context, request}: LoaderArgs) => { + + console.log("LoginLoader", context.auth) // check if user is well logged if (context.auth) { return redirect("/overview") diff --git a/app/routes/logout.action.ts b/app/routes/logout.action.ts index f186141..fbbc146 100644 --- a/app/routes/logout.action.ts +++ b/app/routes/logout.action.ts @@ -1,13 +1,9 @@ import { redirect, type ActionFunction } from "@remix-run/node"; import { getSession, destroySession } from "@models/backoffice/backoffice-cookie.server"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; export const action: ActionFunction = async ({ request }: { request: Request }) => { const session = await getSession(request.headers.get("Cookie")); - // remove token in darchlabs client - Darchlabs.updateApiKey("token") - return redirect("/login", { headers: { "Set-Cookie": await destroySession(session), diff --git a/app/routes/overview.loader.ts b/app/routes/overview.loader.ts index 298cb65..f7f44c4 100644 --- a/app/routes/overview.loader.ts +++ b/app/routes/overview.loader.ts @@ -1,23 +1,29 @@ import { withPagination } from "@middlewares/with-pagination"; -import { type LoaderFunction, json, type LoaderArgs } from "@remix-run/node"; -import { pagination, synchronizers } from "darchlabs"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; +import { type LoaderFunction, json, type LoaderArgs, redirect } from "@remix-run/node"; +import { pagination, synchronizers } from "darchlabs" import { AuthData, withAuth } from "@middlewares/with-auth"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; export type LoaderData = { contracts: synchronizers.Contract[]; auth: AuthData; }; -export const OverviewLoader: LoaderFunction = withAuth(withPagination(async ({ context }: LoaderArgs) => { +export const OverviewLoader: LoaderFunction = withAuth(withPagination(async ({ context, request }: LoaderArgs) => { // get pagination context from middleware - const pagination = context.pagination as pagination.Pagination | {}; + const pagination = context.pagination as pagination.Pagination || {}; // get auth context from middleware const auth = context.auth as AuthData; // get smart contracts - const { contracts, } = await Darchlabs.synchronizers.contracts.listContracts(pagination); + let contracts: synchronizers.Contract[]; + try { + const client = await GetDarchlabsClient(request); + ({ contracts } = await client.synchronizers.contracts.listContracts(pagination)); + } catch (err) { + throw err; + } return json({ contracts, auth }); })); \ No newline at end of file diff --git a/app/routes/overview.metric.action.ts b/app/routes/overview.metric.action.ts index 715eab1..918efd8 100644 --- a/app/routes/overview.metric.action.ts +++ b/app/routes/overview.metric.action.ts @@ -1,7 +1,7 @@ import { type ActionFunction, json } from "@remix-run/node"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; import Axios from "axios"; import { pagination } from "darchlabs"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; import { isAddress } from "ethers"; export type Metric = @@ -156,7 +156,8 @@ export const action: ActionFunction = async ({ request }: { request: Request }) break; } case "events": { - const { events } = await Darchlabs.synchronizers.events.listEventsByAddress(form.address, { + const client = await GetDarchlabsClient(request); + const { events } = await client.synchronizers.events.listEventsByAddress(form.address, { page: 0, limit: 999, }); @@ -165,7 +166,7 @@ export const action: ActionFunction = async ({ request }: { request: Request }) for (let i = 0; i < events.length; i++) { const event = events[i]; const eventName = event?.abi?.name; - const { pagination } = await Darchlabs.synchronizers.events.listEventData(form.address, eventName, { + const { pagination } = await client.synchronizers.events.listEventData(form.address, eventName, { page: 0, limit: 1, }); diff --git a/app/routes/overview.status.action.ts b/app/routes/overview.status.action.ts index 0fe784b..738554f 100644 --- a/app/routes/overview.status.action.ts +++ b/app/routes/overview.status.action.ts @@ -1,8 +1,6 @@ import type { ActionFunction } from "@remix-run/node"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; -import { job } from "@models/jobs.server"; import { Nodes } from "@models/nodes/nodes.server"; -import { da } from "date-fns/locale"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; export type Service = "synchronizers" | "jobs" | "nodes"; @@ -27,9 +25,11 @@ export const action: ActionFunction = async ({ request }: { request: Request }) nodes: { working: 0, failed: 0 }, } as OverviewStatusActionData; + const client = await GetDarchlabsClient(request); + // get data from synchronizers service try { - const { contracts } = await Darchlabs.synchronizers.contracts.listContracts({}); + const { contracts } = await client.synchronizers.contracts.listContracts({}); response.synchronizers.failed = contracts.reduce((sumSc, sc) => { const some = sc.events.some((ev) => ev.status === "error"); @@ -51,14 +51,12 @@ export const action: ActionFunction = async ({ request }: { request: Request }) // get data from jobs service try { - const { data, meta } = await job.ListJobs(); - if (meta === 200) { - response.jobs.failed = data.reduce( - (sum, j) => (j.status === "error" || j.status === "autoStopped" ? sum + 1 : sum), - 0 - ); - response.jobs.working = data.length - response.jobs.failed; - } + const jobs = await client.jobs.listJobs(); + response.jobs.failed = jobs.reduce( + (sum, j) => (j.status === "error" || j.status === "autoStopped" ? sum + 1 : sum), + 0 + ); + response.jobs.working = jobs.length - response.jobs.failed; } catch (err: any) { response.jobs.error = err.mesage; } diff --git a/app/routes/signup.action.tsx b/app/routes/signup.action.tsx index 899e723..e7aea44 100644 --- a/app/routes/signup.action.tsx +++ b/app/routes/signup.action.tsx @@ -1,9 +1,9 @@ import { type ActionArgs, redirect } from "@remix-run/node"; import { getSession, commitSession } from "@models/backoffice/backoffice-cookie.server"; import { Backoffice } from "@models/backoffice/backoffice.server" -import { Darchlabs } from "@models/darchlabs/darchlabs.server" import { AuthData } from "@middlewares/with-auth"; import { z } from 'zod'; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; type SignupActionForm = { email: string; @@ -103,9 +103,6 @@ export const SignupAction = async function action({ request }: ActionArgs) { session.set("backofficeSession", data); const cookie = await commitSession(session); - // set token in darchlabs client - Darchlabs.updateApiKey(token) - // redirect return redirect(redirectTo, { headers: { diff --git a/app/routes/synchronizers.create.evm._index.tsx b/app/routes/synchronizers.create.evm._index.tsx index 527b64a..698c154 100644 --- a/app/routes/synchronizers.create.evm._index.tsx +++ b/app/routes/synchronizers.create.evm._index.tsx @@ -1,7 +1,7 @@ import { type Cookie, withCookie } from "@middlewares/with-cookie"; import { json, type LoaderArgs, type LoaderFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-synchronizers-cookie.server"; import { synchronizers } from "darchlabs"; export type Step = "Network" | "Node" | "Address" | "ABI" | "Confirm"; diff --git a/app/routes/synchronizers.create.evm.abi.action.tsx b/app/routes/synchronizers.create.evm.abi.action.tsx index 5cd29c3..8195600 100644 --- a/app/routes/synchronizers.create.evm.abi.action.tsx +++ b/app/routes/synchronizers.create.evm.abi.action.tsx @@ -1,5 +1,5 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-synchronizers-cookie.server"; import { synchronizers } from "darchlabs"; import { z } from "zod"; import { GetAbiEventSchema } from "@utils/get-abi-schema"; diff --git a/app/routes/synchronizers.create.evm.abi.loader.tsx b/app/routes/synchronizers.create.evm.abi.loader.tsx index 105c39d..e43b81f 100644 --- a/app/routes/synchronizers.create.evm.abi.loader.tsx +++ b/app/routes/synchronizers.create.evm.abi.loader.tsx @@ -1,7 +1,7 @@ import { json, redirect, type LoaderArgs, type LoaderFunction } from "@remix-run/node"; import { synchronizers} from "darchlabs"; import { type Cookie, withCookie } from "@middlewares/with-cookie"; -import { getSession, commitSession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-synchronizers-cookie.server"; import { GetABI } from "@utils/get-abi"; export type ContractsLoaderData = { diff --git a/app/routes/synchronizers.create.evm.address.action.tsx b/app/routes/synchronizers.create.evm.address.action.tsx index f089ea8..d69b5f0 100644 --- a/app/routes/synchronizers.create.evm.address.action.tsx +++ b/app/routes/synchronizers.create.evm.address.action.tsx @@ -1,5 +1,5 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-synchronizers-cookie.server"; import { synchronizers } from "darchlabs"; import { z } from "zod"; import { isAddress } from "ethers"; diff --git a/app/routes/synchronizers.create.evm.confirm.action.tsx b/app/routes/synchronizers.create.evm.confirm.action.tsx index d923ced..feb325e 100644 --- a/app/routes/synchronizers.create.evm.confirm.action.tsx +++ b/app/routes/synchronizers.create.evm.confirm.action.tsx @@ -1,9 +1,8 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, destroySession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, destroySession } from "@models/darchlabs/create-synchronizers-cookie.server"; import { synchronizers } from "darchlabs"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; -import { AxiosError, isAxiosError } from "axios"; import { GetNodeUrlByNetwork } from "@utils/get-nodeurl-by-network"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; type ConfirmActionForm = { baseTo: string; @@ -37,16 +36,12 @@ export const CreateSynchronizersEvmConfirmAction = async function action({ reque // create synchronizer in api try { - await Darchlabs.synchronizers.contracts.createContract(scSession); - } catch (err: AxiosError | unknown) { - let error = "Sorry, something went wrong on the server, please try again later"; - if (isAxiosError(err)) { - error = (err?.response?.data?.error) ? `${error} (${err?.response?.data?.error})` : error - } - + const client = await GetDarchlabsClient(request); + await client.synchronizers.contracts.createContract(scSession); + } catch (err: any) { return { confirm: { - error, + error: `Sorry, something went wrong on the server, please try again later (${err.message})`, }, }; } diff --git a/app/routes/synchronizers.create.evm.confirm.loader.ts b/app/routes/synchronizers.create.evm.confirm.loader.ts index 315f34b..f2cf024 100644 --- a/app/routes/synchronizers.create.evm.confirm.loader.ts +++ b/app/routes/synchronizers.create.evm.confirm.loader.ts @@ -1,7 +1,7 @@ import { type Cookie, withCookie } from "@middlewares/with-cookie"; import { type LoaderArgs, type LoaderFunction, json, redirect } from "@remix-run/node"; import { network, synchronizers } from "darchlabs"; -import { getSession, commitSession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-synchronizers-cookie.server"; export const CreateSynchronizersEvmConfirmLoader: LoaderFunction = withCookie( "scSession", diff --git a/app/routes/synchronizers.create.evm.name.action.tsx b/app/routes/synchronizers.create.evm.name.action.tsx index 1658141..2b7f2b8 100644 --- a/app/routes/synchronizers.create.evm.name.action.tsx +++ b/app/routes/synchronizers.create.evm.name.action.tsx @@ -1,5 +1,5 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-synchronizers-cookie.server"; import { synchronizers } from "darchlabs"; import { z } from "zod"; diff --git a/app/routes/synchronizers.create.evm.node.action.tsx b/app/routes/synchronizers.create.evm.node.action.tsx index 63ffa33..3947985 100644 --- a/app/routes/synchronizers.create.evm.node.action.tsx +++ b/app/routes/synchronizers.create.evm.node.action.tsx @@ -1,5 +1,5 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-synchronizers-cookie.server"; import { synchronizers } from "darchlabs"; import { z } from "zod"; import { ValidateClient } from "@utils/validate-client"; diff --git a/app/routes/synchronizers.create.evm.webhook.action.tsx b/app/routes/synchronizers.create.evm.webhook.action.tsx index d22186d..1f9faa3 100644 --- a/app/routes/synchronizers.create.evm.webhook.action.tsx +++ b/app/routes/synchronizers.create.evm.webhook.action.tsx @@ -1,5 +1,5 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-synchronizers-cookie.server"; import { synchronizers } from "darchlabs"; import { z } from "zod"; diff --git a/app/routes/synchronizers.create.network.action.tsx b/app/routes/synchronizers.create.network.action.tsx index 62e9653..cc0b087 100644 --- a/app/routes/synchronizers.create.network.action.tsx +++ b/app/routes/synchronizers.create.network.action.tsx @@ -1,5 +1,5 @@ import { type ActionArgs, redirect } from "@remix-run/node"; -import { getSession, commitSession } from "@models/synchronizers/create-synchronizers-cookie.server"; +import { getSession, commitSession } from "@models/darchlabs/create-synchronizers-cookie.server"; import { network, synchronizers } from "darchlabs"; import { z } from "zod"; diff --git a/app/routes/synchronizers.delete.action.ts b/app/routes/synchronizers.delete.action.ts index 07bc360..f9658e7 100644 --- a/app/routes/synchronizers.delete.action.ts +++ b/app/routes/synchronizers.delete.action.ts @@ -1,6 +1,6 @@ import type { ActionFunction } from "@remix-run/node"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; import { redirect } from "@remix-run/node"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; type DeleteContractForm = { redirectURL: string; @@ -12,8 +12,13 @@ export const action: ActionFunction = async ({ request }: { request: Request }) const formData = await request.formData(); const { redirectURL, address } = Object.fromEntries(formData) as DeleteContractForm; - // delete smart contract using form data values - await Darchlabs.synchronizers.contracts.deleteContractByAddress(address); + // delete contract from synchronizers service + try { + const client = await GetDarchlabsClient(request); + await client.synchronizers.contracts.deleteContractByAddress(address); + } catch (err: any) { + throw err; + } return redirect(redirectURL); }; diff --git a/app/routes/synchronizers.edit.action.ts b/app/routes/synchronizers.edit.action.ts index 9bd1865..17fe8ed 100644 --- a/app/routes/synchronizers.edit.action.ts +++ b/app/routes/synchronizers.edit.action.ts @@ -1,8 +1,8 @@ import type { ActionFunction } from "@remix-run/node"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; import { redirect } from "@remix-run/node"; import { network } from "darchlabs"; import { ValidateClient } from "@utils/validate-client"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; type EditContractForm = { redirectURL: string; @@ -35,7 +35,8 @@ export const action: ActionFunction = async ({ request }: { request: Request }) // edit smart contract using form data values try { - await Darchlabs.synchronizers.contracts.updateContract(address, { name, nodeURL, webhook }); + const client = await GetDarchlabsClient(request); + await client.synchronizers.contracts.updateContract(address, { name, nodeURL, webhook }); } catch (err: any) { const errMsg = err?.response?.data?.error?.length > 0 ? err.response.data.error : err.error; return { diff --git a/app/routes/synchronizers.loader.ts b/app/routes/synchronizers.loader.ts index 39fed12..cb86462 100644 --- a/app/routes/synchronizers.loader.ts +++ b/app/routes/synchronizers.loader.ts @@ -1,10 +1,9 @@ import { json } from "@remix-run/node"; import type { LoaderArgs, LoaderFunction } from "@remix-run/node"; import { pagination, synchronizers } from "darchlabs"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; import { withPagination } from "@middlewares/with-pagination"; import { AuthData, withAuth } from "@middlewares/with-auth"; - +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; export type ContractsLoaderData = { contracts: synchronizers.Contract[]; @@ -12,12 +11,19 @@ export type ContractsLoaderData = { auth: AuthData; }; -export const ContractsLoader: LoaderFunction = withAuth(withPagination(async ({ context }: LoaderArgs) => { +export const ContractsLoader: LoaderFunction = withAuth(withPagination(async ({ context, request }: LoaderArgs) => { // get pagination context for middleware - const p = context.pagination as pagination.Pagination | {}; + const p = context.pagination as pagination.Pagination || {}; - // get smart contracts - const { contracts, pagination } = await Darchlabs.synchronizers.contracts.listContracts(p); + // get contracts from darchlabs + let contracts: synchronizers.Contract[]; + let pagination: pagination.Pagination; + try { + const client = await GetDarchlabsClient(request); + ({ contracts, pagination } = await client.synchronizers.contracts.listContracts(p)) + } catch (err) { + throw err + } // get auth context from middleware const auth = context.auth as AuthData; diff --git a/app/routes/synchronizers.restart.action.ts b/app/routes/synchronizers.restart.action.ts index e49c833..844f658 100644 --- a/app/routes/synchronizers.restart.action.ts +++ b/app/routes/synchronizers.restart.action.ts @@ -1,6 +1,6 @@ import type { ActionFunction } from "@remix-run/node"; -import { Darchlabs } from "@models/darchlabs/darchlabs.server"; import { redirect } from "@remix-run/node"; +import { GetDarchlabsClient } from "@utils/get-darchlabs-client.server"; type RestartContractForm = { redirectURL: string; @@ -13,7 +13,12 @@ export const action: ActionFunction = async ({ request }: { request: Request }) const { redirectURL, address } = Object.fromEntries(formData) as RestartContractForm; // restart contract using form data values - await Darchlabs.synchronizers.contracts.restartContractByAddress(address); + try { + const client = await GetDarchlabsClient(request); + await client.synchronizers.contracts.restartContractByAddress(address); + } catch (err: any) { + throw err; + } return redirect(redirectURL); }; diff --git a/app/models/darchlabs/darchlabs.server.ts b/app/utils/get-darchlabs-client.server.ts similarity index 69% rename from app/models/darchlabs/darchlabs.server.ts rename to app/utils/get-darchlabs-client.server.ts index 4c707d3..fcb0867 100644 --- a/app/models/darchlabs/darchlabs.server.ts +++ b/app/utils/get-darchlabs-client.server.ts @@ -1,22 +1,17 @@ -import DarchlabsClass from "darchlabs"; +import { redirect } from "@remix-run/node"; +import { GetToken } from "./token.server"; +import Darchlabs from "darchlabs"; import invariant from "tiny-invariant"; -let Darchlabs: DarchlabsClass; +export const GetDarchlabsClient = async (request: Request): Promise => { + const token = await GetToken(request); -declare global { - var __darchlabs__: DarchlabsClass; -} - -if (process.env.NODE_ENV === "production") { - Darchlabs = getClient(); -} else { - if (!global.__darchlabs__) { - global.__darchlabs__ = getClient(); + // redirect to /login use remix redirect if token is empty + if (token === "") { + throw redirect("/login") } - Darchlabs = global.__darchlabs__; -} -function getClient() { + // get url from env vars const { SYNCHORONIZER_API_URL, JOB_API_URL, NODE_API_URL, ETHERSCAN_API_KEY, POLYGONSCAN_API_KEY, ETHEREUM_NODE_URL, POLYGON_NODE_URL, MUMBAI_NODE_URL } = process.env; invariant(typeof SYNCHORONIZER_API_URL === "string", "SYNCHORONIZER_API_URL env var not set"); invariant(typeof JOB_API_URL === "string", "JOB_API_URL env var not set"); @@ -27,13 +22,12 @@ function getClient() { invariant(typeof POLYGON_NODE_URL === "string", "POLYGON_NODE_URL env var not set"); invariant(typeof MUMBAI_NODE_URL === "string", "MUMBAI_NODE_URL env var not set"); - const client = new DarchlabsClass("", { + // create darchlabs client + const client = new Darchlabs(token, { "synchronizers": SYNCHORONIZER_API_URL, "jobs": JOB_API_URL, "nodes": NODE_API_URL, }); return client; -} - -export { Darchlabs }; +} \ No newline at end of file diff --git a/app/utils/token.server.ts b/app/utils/token.server.ts new file mode 100644 index 0000000..966aa9c --- /dev/null +++ b/app/utils/token.server.ts @@ -0,0 +1,21 @@ +import { AuthData } from "@middlewares/with-auth"; +import { getSession, destroySession } from "@models/backoffice/backoffice-cookie.server"; +import { redirect } from "@remix-run/node"; + +export const GetToken = async (request: Request): Promise => { + const session = await getSession(request.headers.get("Cookie")); + const data: AuthData = session.get("backofficeSession"); + const token = data?.token || ""; + + return token +} + +export const DeleteToken = async (request: Request): Promise => { + const session = await getSession(request.headers.get("Cookie")); + + throw redirect("/login", { + headers: { + "Set-Cookie": await destroySession(session), + }, + }); +} diff --git a/package-lock.json b/package-lock.json index c2d49c9..c219194 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "app", - "version": "2.0.0", + "version": "3.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "2.0.0", + "version": "3.1.0", "dependencies": { "@chakra-ui/icons": "^2.0.17", "@chakra-ui/react": "^2.3.4", @@ -26,7 +26,7 @@ "chart": "^0.1.2", "chart.js": "^4.3.0", "cron-validate": "^1.4.5", - "darchlabs": "6.0.0", + "darchlabs": "^6.3.0", "date-fns": "^2.30.0", "ethers": "^6.3.0", "framer-motion": "^6.5.1", @@ -6470,14 +6470,15 @@ "dev": true }, "node_modules/darchlabs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/darchlabs/-/darchlabs-6.0.0.tgz", - "integrity": "sha512-H757JE4w570BP9rTohPOwHPqoxoPm3sExOOeSxs3cm2KmvkltgIQnBA8GyShut2a7rfBEVYpGaefoKKY+Y1uiw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/darchlabs/-/darchlabs-6.3.0.tgz", + "integrity": "sha512-5QoMGLN7pun9bz2T5hMR4EY4i8aAZlh8wwkQa9Ouvg4ZPXRBv+bJyHkQci2anGql/8csel+77sFerNWX4NDB9w==", "dependencies": { "axios": "^1.3.4", "body-parser": "^1.20.2", "buffer": "^6.0.3", "ethers": "^6.7.1", + "eventemitter3": "^5.0.1", "express": "^4.18.2" } }, @@ -8073,6 +8074,11 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -19216,14 +19222,15 @@ "dev": true }, "darchlabs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/darchlabs/-/darchlabs-6.0.0.tgz", - "integrity": "sha512-H757JE4w570BP9rTohPOwHPqoxoPm3sExOOeSxs3cm2KmvkltgIQnBA8GyShut2a7rfBEVYpGaefoKKY+Y1uiw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/darchlabs/-/darchlabs-6.3.0.tgz", + "integrity": "sha512-5QoMGLN7pun9bz2T5hMR4EY4i8aAZlh8wwkQa9Ouvg4ZPXRBv+bJyHkQci2anGql/8csel+77sFerNWX4NDB9w==", "requires": { "axios": "^1.3.4", "body-parser": "^1.20.2", "buffer": "^6.0.3", "ethers": "^6.7.1", + "eventemitter3": "^5.0.1", "express": "^4.18.2" }, "dependencies": { @@ -20414,6 +20421,11 @@ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, + "eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, "execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", diff --git a/package.json b/package.json index 7edd0ad..96e57b5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "sideEffects": false, - "version": "3.1.0", + "version": "4.0.0", "scripts": { "build": "remix build", "dev": "remix dev", @@ -28,7 +28,7 @@ "chart": "^0.1.2", "chart.js": "^4.3.0", "cron-validate": "^1.4.5", - "darchlabs": "6.0.0", + "darchlabs": "^6.3.0", "date-fns": "^2.30.0", "ethers": "^6.3.0", "framer-motion": "^6.5.1",