Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions apps/api/src/chain/services/block-http/block-http.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@ import "@test/mocks/logger-service.mock";

import { BlockHttpService as BlockHttpServiceCommon } from "@akashnetwork/http-sdk";
import { faker } from "@faker-js/faker";
import axios from "axios";

import { BlockHttpService } from "./block-http.service";

describe(BlockHttpService.name, () => {
let service: BlockHttpService;
let blockHttpService: BlockHttpServiceCommon;
it("should get current height", async () => {
const { height, blockHttpService } = setup();

const result = await blockHttpService.getCurrentHeight();

beforeEach(() => {
blockHttpService = new BlockHttpServiceCommon();
service = new BlockHttpService(blockHttpService);
expect(result).toBe(height);
});

it("should get current height", async () => {
const setup = () => {
const blockHttpServiceCommon = new BlockHttpServiceCommon(axios.create());
const blockHttpService = new BlockHttpService(blockHttpServiceCommon);

const height = faker.number.int({ min: 1000000, max: 10000000 });
jest.spyOn(blockHttpService, "getCurrentHeight").mockResolvedValue(height);
const result = await service.getCurrentHeight();
jest.spyOn(blockHttpServiceCommon, "getCurrentHeight").mockResolvedValue(height);

expect(result).toBe(height);
});
return { height, blockHttpServiceCommon, blockHttpService };
};
});
9 changes: 5 additions & 4 deletions apps/api/src/core/providers/http-sdk.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
NodeHttpService,
ProviderHttpService
} from "@akashnetwork/http-sdk";
import axios from "axios";
import { container } from "tsyringe";

import { apiNodeUrl, nodeApiBasePath } from "@src/utils/constants";
Expand All @@ -26,8 +27,8 @@ const SERVICES = [
CosmosHttpService
];

SERVICES.forEach(Service => container.register(Service, { useValue: new Service({ baseURL: apiNodeUrl }) }));
SERVICES.forEach(Service => container.register(Service, { useValue: new Service(axios.create({ baseURL: apiNodeUrl })) }));

container.register(GitHubHttpService, { useValue: new GitHubHttpService({ baseURL: "https://raw.githubusercontent.com" }) });
container.register(CoinGeckoHttpService, { useValue: new CoinGeckoHttpService({ baseURL: "https://api.coingecko.com" }) });
container.register(NodeHttpService, { useValue: new NodeHttpService({ baseURL: nodeApiBasePath }) });
container.register(GitHubHttpService, { useValue: new GitHubHttpService(axios.create({ baseURL: "https://raw.githubusercontent.com" })) });
container.register(CoinGeckoHttpService, { useValue: new CoinGeckoHttpService(axios.create({ baseURL: "https://api.coingecko.com" })) });
container.register(NodeHttpService, { useValue: new NodeHttpService(axios.create({ baseURL: nodeApiBasePath })) });
9 changes: 6 additions & 3 deletions apps/api/test/services/test-wallet.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { BalanceHttpService } from "@akashnetwork/http-sdk";
import type { EncodeObject } from "@cosmjs/proto-signing";
import { coins } from "@cosmjs/proto-signing";
import { calculateFee, GasPrice, SigningStargateClient } from "@cosmjs/stargate";
import axios from "axios";
import dotenv from "dotenv";
import dotenvExpand from "dotenv-expand";
import * as fs from "fs";
Expand All @@ -19,9 +20,11 @@ const MIN_AMOUNTS: Record<string, number> = {
};

export class TestWalletService {
private readonly balanceHttpService = new BalanceHttpService({
baseURL: config!.API_NODE_ENDPOINT
});
private readonly balanceHttpService = new BalanceHttpService(
axios.create({
baseURL: config!.API_NODE_ENDPOINT
})
);

private mnemonics: Record<string, string> = {};

Expand Down
4 changes: 2 additions & 2 deletions apps/deploy-web/src/components/turnstile/Turnstile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ let originalFetch: typeof fetch | undefined;

const addResponseInterceptor = (intercept: (service: Axios, value: AxiosError) => AxiosResponse | Promise<AxiosResponse>) => {
const removes = HTTP_SERVICES.map(service => {
const interceptorId = service.interceptors.response.use(null, error => intercept(service, error));
const interceptorId = service.axios.interceptors.response.use(null, error => intercept(service.axios, error));

return () => {
service.interceptors.response.eject(interceptorId);
service.axios.interceptors.response.eject(interceptorId);
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function useServices() {

function createAppContainer<T extends Factories>(settings: Settings, services: T) {
const di = createChildContainer(rootContainer, {
authzHttpService: () => new AuthzHttpService({ baseURL: settings?.apiEndpoint }),
authzHttpService: () => new AuthzHttpService(rootContainer.createAxios({ baseURL: settings?.apiEndpoint })),
walletBalancesService: () => new WalletBalancesService(di.authzHttpService, di.chainApiHttpClient, browserEnvConfig.NEXT_PUBLIC_MASTER_WALLET_ADDRESS),
certificatesService: () => new CertificatesService(di.chainApiHttpClient),
chainApiHttpClient: () => rootContainer.createAxios({ baseURL: settings?.apiEndpoint }),
Expand Down
2 changes: 1 addition & 1 deletion apps/deploy-web/src/queries/useBalancesQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function useBalances(address?: string, options?: Omit<UseQueryOptions<Bal
return useQuery({
queryKey: QueryKeys.getBalancesKey(address) as QueryKey,
queryFn: () => (address ? di.walletBalancesService.getBalances(address) : null),
enabled: !!address && !!di.authzHttpService.getUri(),
enabled: !!address && !!di.authzHttpService.axios.getUri(),
...options
});
}
24 changes: 18 additions & 6 deletions apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ describe("useGrantsQuery", () => {
};

const authzHttpService = mock<AuthzHttpService>({
defaults: { baseURL: "https://api.akash.network" },
axios: {
defaults: { baseURL: "https://api.akash.network" }
} as AxiosInstance,
getPaginatedDepositDeploymentGrants: jest.fn().mockResolvedValue(mockData)
});
const { result } = setupQuery(() => useGranterGrants("test-address", 0, 1000), {
Expand All @@ -46,7 +48,9 @@ describe("useGrantsQuery", () => {

it("does not fetch when address is not provided", () => {
const authzHttpService = mock<AuthzHttpService>({
defaults: { baseURL: "https://api.akash.network" },
axios: {
defaults: { baseURL: "https://api.akash.network" }
} as AxiosInstance,
getPaginatedDepositDeploymentGrants: jest.fn().mockResolvedValue([])
});
setupQuery(() => useGranterGrants("", 0, 1000), {
Expand All @@ -69,7 +73,9 @@ describe("useGrantsQuery", () => {
}
];
const authzHttpService = mock<AuthzHttpService>({
defaults: { baseURL: "https://api.akash.network" },
axios: {
defaults: { baseURL: "https://api.akash.network" }
} as AxiosInstance,
getAllDepositDeploymentGrants: jest.fn().mockResolvedValue(mockData)
});

Expand All @@ -88,7 +94,9 @@ describe("useGrantsQuery", () => {

it("does not fetch when address is not provided", () => {
const authzHttpService = mock<AuthzHttpService>({
defaults: { baseURL: "https://api.akash.network" },
axios: {
defaults: { baseURL: "https://api.akash.network" }
} as AxiosInstance,
getAllDepositDeploymentGrants: jest.fn().mockResolvedValue([])
});
setupQuery(() => useGranteeGrants(""), {
Expand All @@ -108,7 +116,9 @@ describe("useGrantsQuery", () => {
pagination: { total: 1 }
};
const authzHttpService = mock<AuthzHttpService>({
defaults: { baseURL: "https://api.akash.network" },
axios: {
defaults: { baseURL: "https://api.akash.network" }
} as AxiosInstance,
getPaginatedFeeAllowancesForGranter: jest.fn().mockResolvedValue(mockData)
});

Expand All @@ -127,7 +137,9 @@ describe("useGrantsQuery", () => {

it("does not fetch when address is not provided", () => {
const authzHttpService = mock<AuthzHttpService>({
defaults: { baseURL: "https://api.akash.network" },
axios: {
defaults: { baseURL: "https://api.akash.network" }
} as AxiosInstance,
getPaginatedFeeAllowancesForGranter: jest.fn().mockResolvedValue([])
});
setupQuery(() => useAllowancesIssued("", 0, 1000), {
Expand Down
6 changes: 3 additions & 3 deletions apps/deploy-web/src/queries/useGrantsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function useGranterGrants(
const { authzHttpService } = useServices();
const offset = page * limit;

options.enabled = options.enabled !== false && !!address && !!authzHttpService.defaults.baseURL;
options.enabled = options.enabled !== false && !!address && !!authzHttpService.axios.defaults.baseURL;

return useQuery({
queryKey: QueryKeys.getGranterGrants(address, page, offset),
Expand All @@ -29,7 +29,7 @@ export function useGranterGrants(
export function useGranteeGrants(address: string, options: Omit<UseQueryOptions<DepositDeploymentGrant[]>, "queryKey" | "queryFn"> = {}) {
const { authzHttpService } = useServices();

options.enabled = options.enabled !== false && !!address && !!authzHttpService.defaults.baseURL;
options.enabled = options.enabled !== false && !!address && !!authzHttpService.axios.defaults.baseURL;

return useQuery({
queryKey: QueryKeys.getGranteeGrants(address || "UNDEFINED"),
Expand All @@ -47,7 +47,7 @@ export function useAllowancesIssued(
const { authzHttpService } = useServices();
const offset = page * limit;

options.enabled = options.enabled !== false && !!address && !!authzHttpService.defaults.baseURL;
options.enabled = options.enabled !== false && !!address && !!authzHttpService.axios.defaults.baseURL;

return useQuery({
queryKey: QueryKeys.getAllowancesIssued(address, page, offset),
Expand Down
108 changes: 49 additions & 59 deletions apps/deploy-web/src/services/app-di-container/app-di-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { StripeService } from "@akashnetwork/http-sdk/src/stripe/stripe.service"
import { LoggerService } from "@akashnetwork/logging";
import { getTraceData } from "@sentry/nextjs";
import { MutationCache, QueryCache, QueryClient } from "@tanstack/react-query";
import type { Axios, AxiosInstance, AxiosResponse, CreateAxiosDefaults, InternalAxiosRequestConfig } from "axios";
import type { Axios, AxiosInstance, AxiosRequestConfig, AxiosResponse, CreateAxiosDefaults, InternalAxiosRequestConfig } from "axios";
import axios from "axios";

import { analyticsService } from "@src/services/analytics/analytics.service";
Expand All @@ -27,7 +27,30 @@ import { ProviderProxyService } from "../provider-proxy/provider-proxy.service";

export const createAppRootContainer = (config: ServicesConfig) => {
const apiConfig = { baseURL: config.BASE_API_MAINNET_URL };

const container = createContainer({
getAxiosInstance: () => (config?: AxiosRequestConfig) => {
const { headers, ...defaults } = axios.defaults;

return axios.create({
...defaults,
...config
});
},
axiosWithDefaultInterceptors: () => (config?: AxiosRequestConfig) => {
return container.applyAxiosInterceptors(container.getAxiosInstance(config), {
request: [container.authService.withAnonymousUserHeader]
});
},

defaultAxios: () => container.axiosWithDefaultInterceptors(),
mainnetAxios: () => container.axiosWithDefaultInterceptors(apiConfig),
mainNetAxiosWithNoAnonymousUserHeaderInterceptor: () => container.applyAxiosInterceptors(container.getAxiosInstance(apiConfig)),
managedWalletAxios: () =>
container.axiosWithDefaultInterceptors({
baseURL: container.apiUrlService.getBaseApiUrlFor(config.MANAGED_WALLET_NETWORK_ID)
}),

getTraceData: () => getTraceData,
applyAxiosInterceptors: (): typeof withInterceptors => {
const otelInterceptor = (config: InternalAxiosRequestConfig) => {
Expand All @@ -36,51 +59,37 @@ export const createAppRootContainer = (config: ServicesConfig) => {
if (traceData?.baggage) config.headers.set("Baggage", traceData.baggage);
return config;
};

return (axiosInstance, interceptors?) =>
withInterceptors(axiosInstance, {
request: [config.globalRequestMiddleware, otelInterceptor, ...(interceptors?.request || [])],
response: [...(interceptors?.response || [])]
response: [
response => {
if (response.config.url?.startsWith("/v1/anonymous-users") && response.config.method === "post" && response.status === 200) {
container.analyticsService.track("anonymous_user_created", { category: "user", label: "Anonymous User Created" });
}
return response;
},
response => {
if (response.config.url === "v1/start-trial" && response.config.method === "post" && response.status === 200) {
container.analyticsService.track("trial_started", { category: "billing", label: "Trial Started" });
}
return response;
},
...(interceptors?.response || [])
]
});
},
authService: () => new AuthService(),
user: () =>
container.applyAxiosInterceptors(new UserHttpService(apiConfig), {
request: [container.authService.withAnonymousUserHeader],
response: [
response => {
if (response.config.url?.startsWith("/v1/anonymous-users") && response.config.method === "post" && response.status === 200) {
container.analyticsService.track("anonymous_user_created", { category: "user", label: "Anonymous User Created" });
}
return response;
}
]
}),
stripe: () =>
container.applyAxiosInterceptors(new StripeService(apiConfig), {
request: [container.authService.withAnonymousUserHeader]
}),
tx: () =>
container.applyAxiosInterceptors(new TxHttpService(customRegistry, apiConfig), {
request: [container.authService.withAnonymousUserHeader]
}),
template: () => container.applyAxiosInterceptors(new TemplateHttpService(apiConfig)),
usage: () =>
container.applyAxiosInterceptors(new UsageHttpService(apiConfig), {
request: [container.authService.withAnonymousUserHeader]
}),
auth: () =>
container.applyAxiosInterceptors(new AuthHttpService(apiConfig), {
request: [container.authService.withAnonymousUserHeader]
}),
user: () => new UserHttpService(container.mainnetAxios),
stripe: () => new StripeService(container.mainnetAxios),
tx: () => new TxHttpService(container.mainnetAxios, customRegistry),
template: () => new TemplateHttpService(container.mainNetAxiosWithNoAnonymousUserHeaderInterceptor),
usage: () => new UsageHttpService(container.mainnetAxios),
auth: () => new AuthHttpService(container.mainnetAxios),
providerProxy: () => new ProviderProxyService(container.applyAxiosInterceptors(container.createAxios({ baseURL: config.BASE_PROVIDER_PROXY_URL }), {})),
deploymentSetting: () =>
container.applyAxiosInterceptors(new DeploymentSettingHttpService(apiConfig), {
request: [container.authService.withAnonymousUserHeader]
}),
apiKey: () =>
container.applyAxiosInterceptors(new ApiKeyHttpService(), {
request: [container.authService.withAnonymousUserHeader]
}),
deploymentSetting: () => new DeploymentSettingHttpService(container.mainnetAxios),
apiKey: () => new ApiKeyHttpService(container.defaultAxios),
externalApiHttpClient: () =>
container.createAxios({
headers: {
Expand All @@ -97,26 +106,7 @@ export const createAppRootContainer = (config: ServicesConfig) => {
certificateManager: () => certificateManager,
analyticsService: () => analyticsService,
apiUrlService: config.apiUrlService,
managedWalletService: () =>
container.applyAxiosInterceptors(
new ManagedWalletHttpService(
{
baseURL: container.apiUrlService.getBaseApiUrlFor(config.MANAGED_WALLET_NETWORK_ID)
},
container.analyticsService
),
{
request: [container.authService.withAnonymousUserHeader],
response: [
response => {
if (response.config.url === "v1/start-trial" && response.config.method === "post" && response.status === 200) {
container.analyticsService.track("trial_started", { category: "billing", label: "Trial Started" });
}
return response;
}
]
}
),
managedWalletService: () => new ManagedWalletHttpService(container.managedWalletAxios, container.analyticsService),
queryClient: () =>
new QueryClient({
queryCache: new QueryCache({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const rootContainer = createAppRootContainer({
});

export const services = createChildContainer(rootContainer, {
userProviderService: () => new UserProviderService(),
userProviderService: () => new UserProviderService(services.defaultAxios),
notificationsApi: () =>
createAPIClient({
requestFn,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import type { ApiManagedWalletOutput, ApiWalletOutput } from "@akashnetwork/http-sdk";
import { ManagedWalletHttpService as ManagedWalletHttpServiceOriginal } from "@akashnetwork/http-sdk";
import type { AxiosRequestConfig } from "axios";
import type { AxiosInstance } from "axios";

import type { AnalyticsService } from "@src/services/analytics/analytics.service";

export class ManagedWalletHttpService extends ManagedWalletHttpServiceOriginal {
private checkoutSessionId: string | null = null;

constructor(
config: AxiosRequestConfig,
axios: AxiosInstance,
private readonly analyticsService: AnalyticsService
) {
super(config);
super(axios);

this.extractSessionResults();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { HttpService } from "@akashnetwork/http-sdk";
import type { UserProfile } from "@auth0/nextjs-auth0/client";
import type { InternalAxiosRequestConfig } from "axios";
import type { AxiosInstance, InternalAxiosRequestConfig } from "axios";

import { ANONYMOUS_USER_TOKEN_KEY } from "@src/config/auth.config";

export class UserProviderService extends HttpService {
constructor() {
super();
constructor(axios: AxiosInstance) {
super(axios);

this.getProfile = this.getProfile.bind(this);
this.interceptors.request.use((config: InternalAxiosRequestConfig) => {
this.axios.interceptors.request.use((config: InternalAxiosRequestConfig) => {
const token = localStorage.getItem(ANONYMOUS_USER_TOKEN_KEY);

if (token) {
Expand Down
Loading
Loading