From a5ca8313c9ef545336889d8a536e4cf92c537c61 Mon Sep 17 00:00:00 2001 From: Serhii Stotskyi Date: Wed, 29 Jan 2025 14:44:51 +0200 Subject: [PATCH] feat: adjusts logic to send provider and chain details to provider proxy (#742) --- .../deployments/DeploymentLeaseShell.tsx | 2 +- .../components/deployments/DeploymentLogs.tsx | 2 +- .../src/components/deployments/LeaseRow.tsx | 9 +-- .../components/deployments/ManifestUpdate.tsx | 9 ++- .../src/components/new-deployment/BidRow.tsx | 2 +- .../components/new-deployment/CreateLease.tsx | 7 +- .../providers/LeaseListContainer.tsx | 4 +- .../components/providers/ProviderDetail.tsx | 2 +- .../components/providers/ProviderRawData.tsx | 4 +- .../src/config/env-config.schema.ts | 3 +- .../src/context/ServicesProvider/index.tsx | 13 ++++ .../src/hooks/useScopedFetchProviderUrl.ts | 25 +++++++ apps/deploy-web/src/pages/_app.tsx | 5 +- apps/deploy-web/src/queries/useLeaseQuery.ts | 36 +++++----- .../src/queries/useProvidersQuery.ts | 65 ++++++++++--------- .../http-factory/http-factory.service.ts | 18 +++-- .../src/services/http/http-browser.service.ts | 5 +- .../src/services/http/http-server.service.ts | 5 +- .../provider-proxy/provider-proxy.service.ts | 38 +++++++++++ apps/deploy-web/src/utils/deploymentUtils.ts | 36 +++++----- 20 files changed, 199 insertions(+), 91 deletions(-) create mode 100644 apps/deploy-web/src/context/ServicesProvider/index.tsx create mode 100644 apps/deploy-web/src/hooks/useScopedFetchProviderUrl.ts create mode 100644 apps/deploy-web/src/services/provider-proxy/provider-proxy.service.ts diff --git a/apps/deploy-web/src/components/deployments/DeploymentLeaseShell.tsx b/apps/deploy-web/src/components/deployments/DeploymentLeaseShell.tsx index be0ccc7c1..a0b11093b 100644 --- a/apps/deploy-web/src/components/deployments/DeploymentLeaseShell.tsx +++ b/apps/deploy-web/src/components/deployments/DeploymentLeaseShell.tsx @@ -42,7 +42,7 @@ export const DeploymentLeaseShell: React.FunctionComponent = ({ leases }) data: leaseStatus, refetch: getLeaseStatus, isFetching: isLoadingStatus - } = useLeaseStatus(providerInfo?.hostUri || "", selectedLease as LeaseDto, { + } = useLeaseStatus(providerInfo, selectedLease as LeaseDto, { enabled: false }); const currentUrl = useRef(null); diff --git a/apps/deploy-web/src/components/deployments/DeploymentLogs.tsx b/apps/deploy-web/src/components/deployments/DeploymentLogs.tsx index eb25712ca..a714d2062 100644 --- a/apps/deploy-web/src/components/deployments/DeploymentLogs.tsx +++ b/apps/deploy-web/src/components/deployments/DeploymentLogs.tsx @@ -54,7 +54,7 @@ export const DeploymentLogs: React.FunctionComponent = ({ leases, selecte data: leaseStatus, refetch: getLeaseStatus, isFetching: isLoadingStatus - } = useLeaseStatus(providerInfo?.hostUri || "", selectedLease as LeaseDto, { + } = useLeaseStatus(providerInfo, selectedLease as LeaseDto, { enabled: false }); const { sendJsonMessage } = useWebSocket(browserEnvConfig.NEXT_PUBLIC_PROVIDER_PROXY_URL_WS, { diff --git a/apps/deploy-web/src/components/deployments/LeaseRow.tsx b/apps/deploy-web/src/components/deployments/LeaseRow.tsx index 049fecdef..13af9209e 100644 --- a/apps/deploy-web/src/components/deployments/LeaseRow.tsx +++ b/apps/deploy-web/src/components/deployments/LeaseRow.tsx @@ -18,12 +18,12 @@ import { PricePerMonth } from "@src/components/shared/PricePerMonth"; import { SpecDetail } from "@src/components/shared/SpecDetail"; import { StatusPill } from "@src/components/shared/StatusPill"; import { useCertificate } from "@src/context/CertificateProvider"; -import { LocalCert } from "@src/context/CertificateProvider/CertificateProviderContext"; import { useLocalNotes } from "@src/context/LocalNoteProvider"; import { getSplitText } from "@src/hooks/useShortText"; import { useBidInfo } from "@src/queries/useBidQuery"; import { useLeaseStatus } from "@src/queries/useLeaseQuery"; import { useProviderStatus } from "@src/queries/useProvidersQuery"; +import networkStore from "@src/store/networkStore"; import { LeaseDto } from "@src/types/deployment"; import { ApiProviderList } from "@src/types/provider"; import { copyTextToClipboard } from "@src/utils/copyClipboard"; @@ -63,7 +63,7 @@ export const LeaseRow = React.forwardRef( error, refetch: getLeaseStatus, isLoading: isLoadingLeaseStatus - } = useLeaseStatus(provider?.hostUri || "", lease, { + } = useLeaseStatus(provider, lease, { enabled: isLeaseActive && !isServicesAvailable && !!provider?.hostUri && !!localCert, refetchInterval: 10_000, onSuccess: leaseStatus => { @@ -72,7 +72,7 @@ export const LeaseRow = React.forwardRef( } } }); - const { isLoading: isLoadingProviderStatus, refetch: getProviderStatus } = useProviderStatus(provider?.hostUri || "", { + const { isLoading: isLoadingProviderStatus, refetch: getProviderStatus } = useProviderStatus(provider, { enabled: false, retry: false }); @@ -117,12 +117,13 @@ export const LeaseRow = React.forwardRef( setActiveTab("EDIT"); } + const chainNetwork = networkStore.useSelectedNetworkId(); async function sendManifest() { setIsSendingManifest(true); try { const manifest = deploymentData.getManifest(parsedManifest, true); - await sendManifestToProvider(provider as ApiProviderList, manifest, dseq, localCert as LocalCert); + await sendManifestToProvider(provider, manifest, { dseq, localCert, chainNetwork }); enqueueSnackbar(, { variant: "success", autoHideDuration: 10_000 }); diff --git a/apps/deploy-web/src/components/deployments/ManifestUpdate.tsx b/apps/deploy-web/src/components/deployments/ManifestUpdate.tsx index 91b98519b..bf2ee0fc1 100644 --- a/apps/deploy-web/src/components/deployments/ManifestUpdate.tsx +++ b/apps/deploy-web/src/components/deployments/ManifestUpdate.tsx @@ -11,10 +11,10 @@ import { LinearLoadingSkeleton } from "@src/components/shared/LinearLoadingSkele import { LinkTo } from "@src/components/shared/LinkTo"; import ViewPanel from "@src/components/shared/ViewPanel"; import { useCertificate } from "@src/context/CertificateProvider"; -import { LocalCert } from "@src/context/CertificateProvider/CertificateProviderContext"; import { useSettings } from "@src/context/SettingsProvider"; import { useWallet } from "@src/context/WalletProvider"; import { useProviderList } from "@src/queries/useProvidersQuery"; +import networkStore from "@src/store/networkStore"; import { AnalyticsCategory, AnalyticsEvents } from "@src/types/analytics"; import { DeploymentDto, LeaseDto } from "@src/types/deployment"; import { ApiProviderList } from "@src/types/provider"; @@ -122,9 +122,14 @@ export const ManifestUpdate: React.FunctionComponent = ({ window.open("https://akash.network/docs/deployments/akash-cli/installation/#update-the-deployment", "_blank"); } + const chainNetwork = networkStore.useSelectedNetworkId(); async function sendManifest(providerInfo: ApiProviderList, manifest: any) { try { - return await sendManifestToProvider(providerInfo, manifest, deployment.dseq, localCert as LocalCert); + return await sendManifestToProvider(providerInfo, manifest, { + dseq: deployment.dseq, + localCert, + chainNetwork + }); } catch (err) { enqueueSnackbar(, { variant: "error", autoHideDuration: null }); throw err; diff --git a/apps/deploy-web/src/components/new-deployment/BidRow.tsx b/apps/deploy-web/src/components/new-deployment/BidRow.tsx index 23a92c5a0..30ea3a2cb 100644 --- a/apps/deploy-web/src/components/new-deployment/BidRow.tsx +++ b/apps/deploy-web/src/components/new-deployment/BidRow.tsx @@ -38,7 +38,7 @@ export const BidRow: React.FunctionComponent = ({ testIndex, bid, selecte isLoading: isLoadingStatus, refetch: fetchProviderStatus, error - } = useProviderStatus(provider?.hostUri, { + } = useProviderStatus(provider, { enabled: false, retry: false }); diff --git a/apps/deploy-web/src/components/new-deployment/CreateLease.tsx b/apps/deploy-web/src/components/new-deployment/CreateLease.tsx index 17aa23b72..f600c2d4c 100644 --- a/apps/deploy-web/src/components/new-deployment/CreateLease.tsx +++ b/apps/deploy-web/src/components/new-deployment/CreateLease.tsx @@ -23,13 +23,13 @@ import { useRouter } from "next/navigation"; import { event } from "nextjs-google-analytics"; import { useSnackbar } from "notistack"; -import { LocalCert } from "@src/context/CertificateProvider/CertificateProviderContext"; import { useWallet } from "@src/context/WalletProvider"; import { useManagedDeploymentConfirm } from "@src/hooks/useManagedDeploymentConfirm"; import { useWhen } from "@src/hooks/useWhen"; import { useBidList } from "@src/queries/useBidQuery"; import { useDeploymentDetail } from "@src/queries/useDeploymentQuery"; import { useProviderList } from "@src/queries/useProvidersQuery"; +import networkStore from "@src/store/networkStore"; import { AnalyticsCategory, AnalyticsEvents } from "@src/types/analytics"; import { BidDto } from "@src/types/deployment"; import { RouteStep } from "@src/types/route-steps.type"; @@ -108,6 +108,7 @@ export const CreateLease: React.FunctionComponent = ({ dseq }) => { useWhen(hasActiveBid, () => selectBid(activeBid)); + const chainNetwork = networkStore.useSelectedNetworkId(); const sendManifest = useCallback(async () => { setIsSendingManifest(true); const bidKeys = Object.keys(selectedBids); @@ -141,7 +142,7 @@ export const CreateLease: React.FunctionComponent = ({ dseq }) => { if (!provider) { throw new Error("Provider not found"); } - await sendManifestToProvider(provider, mani, dseq, localCert as LocalCert); + await sendManifestToProvider(provider, mani, { dseq, localCert, chainNetwork }); } router.replace(UrlService.deploymentDetails(dseq, "EVENTS", "events")); } catch (err) { @@ -154,7 +155,7 @@ export const CreateLease: React.FunctionComponent = ({ dseq }) => { setIsSendingManifest(false); } - }, [selectedBids, dseq, providers, localCert, isManaged, enqueueSnackbar, closeSnackbar, router]); + }, [selectedBids, dseq, providers, localCert, isManaged, enqueueSnackbar, closeSnackbar, router, chainNetwork]); // Filter bids useEffect(() => { diff --git a/apps/deploy-web/src/components/providers/LeaseListContainer.tsx b/apps/deploy-web/src/components/providers/LeaseListContainer.tsx index 6ebf6d752..fc7d87102 100644 --- a/apps/deploy-web/src/components/providers/LeaseListContainer.tsx +++ b/apps/deploy-web/src/components/providers/LeaseListContainer.tsx @@ -5,7 +5,7 @@ import { useWallet } from "@src/context/WalletProvider"; import { useAllLeases } from "@src/queries/useLeaseQuery"; import { useProviderDetail, useProviderStatus } from "@src/queries/useProvidersQuery"; import { LeaseDto } from "@src/types/deployment"; -import { ClientProviderDetailWithStatus } from "@src/types/provider"; +import { ApiProviderList, ClientProviderDetailWithStatus } from "@src/types/provider"; import { domainName, UrlService } from "@src/utils/urlUtils"; import Layout from "../layout/Layout"; import { CustomNextSeo } from "../shared/CustomNextSeo"; @@ -32,7 +32,7 @@ export const LeaseListContainer: React.FunctionComponent = ({ owner }) => data: providerStatus, isLoading: isLoadingStatus, refetch: getProviderStatus - } = useProviderStatus(provider?.hostUri || "", { + } = useProviderStatus(provider as ApiProviderList, { enabled: false, retry: false, onSuccess: () => { diff --git a/apps/deploy-web/src/components/providers/ProviderDetail.tsx b/apps/deploy-web/src/components/providers/ProviderDetail.tsx index de49902fe..f9051a8e8 100644 --- a/apps/deploy-web/src/components/providers/ProviderDetail.tsx +++ b/apps/deploy-web/src/components/providers/ProviderDetail.tsx @@ -44,7 +44,7 @@ export const ProviderDetail: React.FunctionComponent = ({ owner, _provide }); const { data: leases, isFetching: isLoadingLeases, refetch: getLeases } = useAllLeases(address, { enabled: false }); const { data: providerAttributesSchema, isFetching: isLoadingSchema } = useProviderAttributesSchema(); - const { isLoading: isLoadingStatus, refetch: getProviderStatus } = useProviderStatus(provider?.hostUri || "", { + const { isLoading: isLoadingStatus, refetch: getProviderStatus } = useProviderStatus(provider, { enabled: true, retry: false, onSuccess: _providerStatus => { diff --git a/apps/deploy-web/src/components/providers/ProviderRawData.tsx b/apps/deploy-web/src/components/providers/ProviderRawData.tsx index 8894daead..cc0fa7f45 100644 --- a/apps/deploy-web/src/components/providers/ProviderRawData.tsx +++ b/apps/deploy-web/src/components/providers/ProviderRawData.tsx @@ -5,7 +5,7 @@ import { DynamicReactJson } from "@src/components/shared/DynamicJsonView"; import { useWallet } from "@src/context/WalletProvider"; import { useAllLeases } from "@src/queries/useLeaseQuery"; import { useProviderDetail, useProviderStatus } from "@src/queries/useProvidersQuery"; -import { ClientProviderDetailWithStatus } from "@src/types/provider"; +import { ApiProviderList, ClientProviderDetailWithStatus } from "@src/types/provider"; import { domainName, UrlService } from "@src/utils/urlUtils"; import Layout from "../layout/Layout"; import { CustomNextSeo } from "../shared/CustomNextSeo"; @@ -30,7 +30,7 @@ export const ProviderRawData: React.FunctionComponent = ({ owner }) => { data: providerStatus, isLoading: isLoadingStatus, refetch: getProviderStatus - } = useProviderStatus(provider?.hostUri || "", { + } = useProviderStatus(provider as ApiProviderList, { enabled: false, retry: false, onSuccess: () => { diff --git a/apps/deploy-web/src/config/env-config.schema.ts b/apps/deploy-web/src/config/env-config.schema.ts index d7aa06555..f793892f9 100644 --- a/apps/deploy-web/src/config/env-config.schema.ts +++ b/apps/deploy-web/src/config/env-config.schema.ts @@ -46,7 +46,8 @@ export const serverEnvSchema = browserEnvSchema.extend({ GITHUB_CLIENT_SECRET: z.string(), BITBUCKET_CLIENT_SECRET: z.string(), GITLAB_CLIENT_SECRET: z.string(), - NEXT_PUBLIC_CI_CD_IMAGE_NAME: z.string() + NEXT_PUBLIC_CI_CD_IMAGE_NAME: z.string(), + NEXT_PUBLIC_PROVIDER_PROXY_URL: z.string() }); export type BrowserEnvConfig = z.infer; diff --git a/apps/deploy-web/src/context/ServicesProvider/index.tsx b/apps/deploy-web/src/context/ServicesProvider/index.tsx new file mode 100644 index 000000000..453a64e25 --- /dev/null +++ b/apps/deploy-web/src/context/ServicesProvider/index.tsx @@ -0,0 +1,13 @@ +import React, { useContext } from "react"; + +import { services as defaultServices } from "@src/services/http/http-browser.service"; + +const ServicesContext = React.createContext(defaultServices); + +export const ServicesProvider: React.FC<{ children: React.ReactNode; services?: Partial }> = ({ children, services }) => { + return {children}; +}; + +export function useServices() { + return useContext(ServicesContext); +} diff --git a/apps/deploy-web/src/hooks/useScopedFetchProviderUrl.ts b/apps/deploy-web/src/hooks/useScopedFetchProviderUrl.ts new file mode 100644 index 000000000..1ce457a9e --- /dev/null +++ b/apps/deploy-web/src/hooks/useScopedFetchProviderUrl.ts @@ -0,0 +1,25 @@ +import { useCallback } from "react"; +import { AxiosResponse } from "axios"; + +import { useServices } from "@src/context/ServicesProvider"; +import { ProviderIdentity, ProviderProxyPayload } from "@src/services/provider-proxy/provider-proxy.service"; +import networkStore from "@src/store/networkStore"; + +export function useScopedFetchProviderUrl(provider: ProviderIdentity | undefined | null): ScopedFetchProviderUrl { + const chainNetwork = networkStore.useSelectedNetworkId(); + const { providerProxy } = useServices(); + return useCallback( + (url, options) => { + if (!provider) return new Promise(() => {}); + return providerProxy.fetchProviderUrl(url, { + ...options, + chainNetwork, + providerIdentity: provider + }); + }, + [provider?.hostUri, provider?.owner, chainNetwork] + ); +} + +export type ScopedFetchProviderUrlOptions = Omit; +export type ScopedFetchProviderUrl = (url: string, options?: ScopedFetchProviderUrlOptions) => Promise>; diff --git a/apps/deploy-web/src/pages/_app.tsx b/apps/deploy-web/src/pages/_app.tsx index 704816178..2f7f3d54c 100644 --- a/apps/deploy-web/src/pages/_app.tsx +++ b/apps/deploy-web/src/pages/_app.tsx @@ -27,6 +27,7 @@ import { CustomChainProvider } from "@src/context/CustomChainProvider"; import { ColorModeProvider } from "@src/context/CustomThemeContext"; import { LocalNoteProvider } from "@src/context/LocalNoteProvider"; import { PricingProvider } from "@src/context/PricingProvider/PricingProvider"; +import { ServicesProvider } from "@src/context/ServicesProvider"; import { SettingsProvider } from "@src/context/SettingsProvider"; import { TemplatesProvider } from "@src/context/TemplatesProvider"; import { WalletProvider } from "@src/context/WalletProvider"; @@ -73,7 +74,9 @@ const App: React.FunctionComponent = props => { - + + + diff --git a/apps/deploy-web/src/queries/useLeaseQuery.ts b/apps/deploy-web/src/queries/useLeaseQuery.ts index 379c240c6..f0941eafc 100644 --- a/apps/deploy-web/src/queries/useLeaseQuery.ts +++ b/apps/deploy-web/src/queries/useLeaseQuery.ts @@ -1,9 +1,8 @@ import { useQuery } from "react-query"; -import axios from "axios"; -import { browserEnvConfig } from "@src/config/browser-env.config"; -import { LocalCert } from "@src/context/CertificateProvider/CertificateProviderContext"; +import { useScopedFetchProviderUrl } from "@src/hooks/useScopedFetchProviderUrl"; import { LeaseDto, RpcLease } from "@src/types/deployment"; +import { ApiProviderList } from "@src/types/provider"; import { ApiUrlService, loadWithPagination } from "@src/utils/apiUtils"; import { leaseToDto } from "@src/utils/deploymentDetailUtils"; import { useCertificate } from "../context/CertificateProvider"; @@ -46,21 +45,20 @@ export function useAllLeases(address: string, options = {}) { return useQuery(QueryKeys.getAllLeasesKey(address), () => getAllLeases(settings.apiEndpoint, address), options); } -async function getLeaseStatus(providerUri: string, lease: LeaseDto, localCert: LocalCert | null) { - if (!providerUri) return null; - - const leaseStatusPath = `${providerUri}/lease/${lease.dseq}/${lease.gseq}/${lease.oseq}/status`; - const response = await axios.post(browserEnvConfig.NEXT_PUBLIC_PROVIDER_PROXY_URL, { - method: "GET", - url: leaseStatusPath, - certPem: localCert?.certPem, - keyPem: localCert?.keyPem - }); - - return response.data; -} - -export function useLeaseStatus(providerUri: string, lease: LeaseDto, options) { +export function useLeaseStatus(provider: ApiProviderList | undefined, lease: LeaseDto, options) { const { localCert } = useCertificate(); - return useQuery(QueryKeys.getLeaseStatusKey(lease?.dseq, lease?.gseq, lease?.oseq), () => getLeaseStatus(providerUri, lease, localCert), options); + const fetchProviderUrl = useScopedFetchProviderUrl(provider); + + return useQuery( + QueryKeys.getLeaseStatusKey(lease?.dseq, lease?.gseq, lease?.oseq), + async () => { + const response = await fetchProviderUrl(`/lease/${lease.dseq}/${lease.gseq}/${lease.oseq}/status`, { + method: "GET", + certPem: localCert?.certPem, + keyPem: localCert?.keyPem + }); + return response.data; + }, + options + ); } diff --git a/apps/deploy-web/src/queries/useProvidersQuery.ts b/apps/deploy-web/src/queries/useProvidersQuery.ts index 5fd03e886..5f5d6c6a4 100644 --- a/apps/deploy-web/src/queries/useProvidersQuery.ts +++ b/apps/deploy-web/src/queries/useProvidersQuery.ts @@ -1,40 +1,45 @@ -import { useQuery } from "react-query"; +import { useQuery, UseQueryResult } from "react-query"; import axios from "axios"; -import { browserEnvConfig } from "@src/config/browser-env.config"; -import { ApiProviderDetail, ApiProviderList, ApiProviderRegion, Auditor } from "@src/types/provider"; +import { useServices } from "@src/context/ServicesProvider"; +import { useScopedFetchProviderUrl } from "@src/hooks/useScopedFetchProviderUrl"; +import { ApiProviderDetail, ApiProviderList, ApiProviderRegion, Auditor, ProviderStatus, ProviderVersion } from "@src/types/provider"; import { ProviderAttributesSchema } from "@src/types/providerAttributes"; import { ApiUrlService } from "@src/utils/apiUtils"; import { getNetworkCapacityDto, providerStatusToDto } from "@src/utils/providerUtils"; import { QueryKeys } from "./queryKeys"; -async function getProviderDetail(owner: string): Promise { - if (!owner) return null; - - const response = await axios.get(ApiUrlService.providerDetail(owner)); - - return response.data; -} - -export function useProviderDetail(owner: string, options) { - return useQuery(QueryKeys.getProviderDetailKey(owner), () => getProviderDetail(owner), options); -} - -async function getProviderStatus(providerUri: string) { - if (!providerUri) return null; - - try { - const statusResponse = await axios.post(browserEnvConfig.NEXT_PUBLIC_PROVIDER_PROXY_URL, { url: `${providerUri}/status`, method: "GET" }); - const versionResponse = await axios.post(browserEnvConfig.NEXT_PUBLIC_PROVIDER_PROXY_URL, { url: `${providerUri}/version`, method: "GET" }); - return providerStatusToDto(statusResponse.data, versionResponse?.data || {}); - } catch (error) { - console.log(error); - throw error; - } -} - -export function useProviderStatus(providerUri: string, options = {}) { - return useQuery(QueryKeys.getProviderStatusKey(providerUri), () => getProviderStatus(providerUri), options); +export function useProviderDetail(owner: string, options): UseQueryResult { + const services = useServices(); + return useQuery( + QueryKeys.getProviderDetailKey(owner), + async () => { + if (!owner) return null; + const response = await services.axios.get(ApiUrlService.providerDetail(owner)); + return response.data; + }, + options + ); +} + +export function useProviderStatus(provider: ApiProviderList | undefined | null, options = {}) { + const fetchProviderUrl = useScopedFetchProviderUrl(provider); + return useQuery( + QueryKeys.getProviderStatusKey(provider?.hostUri || ""), + async () => { + try { + const [statusResponse, versionResponse] = await Promise.all([ + fetchProviderUrl("/status"), + fetchProviderUrl("/version") + ]); + return providerStatusToDto(statusResponse.data, versionResponse.data || {}); + } catch (error) { + console.log(error); + throw error; + } + }, + options + ); } async function getNetworkCapacity() { diff --git a/apps/deploy-web/src/services/http-factory/http-factory.service.ts b/apps/deploy-web/src/services/http-factory/http-factory.service.ts index 7c73ca6ff..c753ef0c2 100644 --- a/apps/deploy-web/src/services/http-factory/http-factory.service.ts +++ b/apps/deploy-web/src/services/http-factory/http-factory.service.ts @@ -1,21 +1,22 @@ -import { AuthHttpService, TxHttpService, UserHttpService } from "@akashnetwork/http-sdk"; +import { AuthHttpService, TemplateHttpService, TxHttpService, UserHttpService } from "@akashnetwork/http-sdk"; import { StripeService } from "@akashnetwork/http-sdk/src/stripe/stripe.service"; -import { TemplateHttpService } from "@akashnetwork/http-sdk/src/template/template-http.service"; +import axios from "axios"; import { event } from "nextjs-google-analytics"; -import type { BrowserEnvConfig, ServerEnvConfig } from "@src/config/env-config.schema"; import { authService } from "@src/services/auth/auth.service"; import { AnalyticsCategory, AnalyticsEvents } from "@src/types/analytics"; import { customRegistry } from "@src/utils/customRegistry"; +import { ProviderProxyService } from "../provider-proxy/provider-proxy.service"; -export const createServices = (config: Pick | Pick) => { - const apiConfig = { baseURL: "BASE_API_MAINNET_URL" in config ? config.BASE_API_MAINNET_URL : config.NEXT_PUBLIC_BASE_API_MAINNET_URL }; +export const createServices = (config: ServicesConfig) => { + const apiConfig = { baseURL: config.BASE_API_MAINNET_URL }; const user = new UserHttpService(apiConfig); const stripe = new StripeService(apiConfig); const tx = new TxHttpService(customRegistry, apiConfig); const template = new TemplateHttpService(apiConfig); const auth = new AuthHttpService(apiConfig); + const providerProxy = new ProviderProxyService({ baseURL: config.BASE_PROVIDER_PROXY_URL }); user.interceptors.request.use(authService.withAnonymousUserHeader); stripe.interceptors.request.use(authService.withAnonymousUserHeader); @@ -29,5 +30,10 @@ export const createServices = (config: Pick) { + super(config); + } + + fetchProviderUrl(url: string, options: ProviderProxyPayload): Promise> { + const { chainNetwork, providerIdentity, timeout, ...params } = options; + return this.post( + "/", + { + ...params, + method: options.method || "GET", + url: providerIdentity.hostUri + url, + providerAddress: providerIdentity.owner, + network: options.chainNetwork + }, + { timeout } + ); + } +} + +export interface ProviderProxyPayload { + method?: "GET" | "POST" | "PUT" | "DELETE"; + certPem?: string; + keyPem?: string; + body?: string; + timeout?: number; + chainNetwork: string; + providerIdentity: ProviderIdentity; +} + +export interface ProviderIdentity { + owner: string; + hostUri: string; +} diff --git a/apps/deploy-web/src/utils/deploymentUtils.ts b/apps/deploy-web/src/utils/deploymentUtils.ts index 8cde1a96a..d283d179f 100644 --- a/apps/deploy-web/src/utils/deploymentUtils.ts +++ b/apps/deploy-web/src/utils/deploymentUtils.ts @@ -1,47 +1,53 @@ -import axios from "axios"; +import { AxiosResponse } from "axios"; -import { browserEnvConfig } from "@src/config/browser-env.config"; import { LocalCert } from "@src/context/CertificateProvider/CertificateProviderContext"; +import { services } from "@src/services/http/http-browser.service"; import { ApiProviderList } from "@src/types/provider"; import { wait } from "./timer"; -export const sendManifestToProvider = async (providerInfo: ApiProviderList, manifest: any, dseq: string, localCert: LocalCert) => { +export interface SendManifestToProviderOptions { + dseq: string; + localCert?: LocalCert | null; + chainNetwork: string; +} + +export const sendManifestToProvider = async (providerInfo: ApiProviderList | undefined | null, manifest: unknown, options: SendManifestToProviderOptions) => { + if (!providerInfo) return; console.log("Sending manifest to " + providerInfo?.owner); let jsonStr = JSON.stringify(manifest); jsonStr = jsonStr.replaceAll('"quantity":{"val', '"size":{"val'); - // Waiting for 5 sec for provider to have lease + // Waiting for provider to have lease await wait(5000); - let response; + let response: AxiosResponse | undefined; - for (let i = 1; i <= 3; i++) { + for (let i = 1; i <= 3 && !response; i++) { console.log("Try #" + i); try { if (!response) { - response = await axios.post(browserEnvConfig.NEXT_PUBLIC_PROVIDER_PROXY_URL, { + response = await services.providerProxy.fetchProviderUrl(`/deployment/${options.dseq}/manifest`, { method: "PUT", - url: providerInfo.hostUri + "/deployment/" + dseq + "/manifest", - certPem: localCert?.certPem, - keyPem: localCert?.keyPem, + certPem: options.localCert?.certPem, + keyPem: options.localCert?.keyPem, body: jsonStr, - timeout: 60_000 + timeout: 60_000, + providerIdentity: providerInfo, + chainNetwork: options.chainNetwork }); - - i = 3; } } catch (err) { if (err.includes && err.includes("no lease for deployment") && i < 3) { console.log("Lease not found, retrying..."); - await wait(6000); // Waiting for 6 sec + await wait(6000); } else { throw new Error(err?.response?.data || err); } } } - // Waiting for 5 sec for provider to boot up workload + // Waiting for provider to boot up workload await wait(5000); return response;