From 385bacd8262ddf53d3e4ef7345ec8d4019f3254b Mon Sep 17 00:00:00 2001 From: Yaroslav Grishajev Date: Mon, 29 Jul 2024 15:25:05 +0200 Subject: [PATCH] refactor(http): extract http services to the package refs #247 --- apps/api/package.json | 2 +- .../controllers/wallet/wallet.controller.ts | 1 + apps/api/src/db/dbConnection.ts | 10 +- apps/deploy-web/package.json | 4 +- .../context/WalletProvider/WalletProvider.tsx | 3 +- .../src/pages/api/auth/[...auth0].ts | 10 +- .../src/queries/useAnonymousUserQuery.ts | 2 +- .../src/queries/useManagedWalletQuery.ts | 2 +- .../src/services/api-http/api-http.service.ts | 29 ------ .../src/services/auth/auth-http.service.ts | 9 +- .../src/services/http/http.service.ts | 10 ++ .../src/services/tx-http/tx-http.service.ts | 29 ------ apps/indexer/package.json | 2 +- apps/provider-proxy/package.json | 2 +- apps/stats-web/package.json | 2 +- package-lock.json | 93 +++++++++++++++++-- packages/http-sdk/package.json | 8 +- .../http-sdk/src/api-http/api-http.service.ts | 24 +++++ packages/http-sdk/src/index.ts | 4 + .../managed-wallet-http.service.ts | 8 +- .../http-sdk/src/tx-http/tx-http.service.ts | 33 +++++++ .../src}/user-http/user-http.service.ts | 14 ++- packages/http-sdk/tsconfig.build.json | 11 +++ packages/http-sdk/tsconfig.json | 5 + 24 files changed, 215 insertions(+), 102 deletions(-) delete mode 100644 apps/deploy-web/src/services/api-http/api-http.service.ts create mode 100644 apps/deploy-web/src/services/http/http.service.ts delete mode 100644 apps/deploy-web/src/services/tx-http/tx-http.service.ts create mode 100644 packages/http-sdk/src/api-http/api-http.service.ts rename {apps/deploy-web/src/services => packages/http-sdk/src}/managed-wallet-http/managed-wallet-http.service.ts (59%) create mode 100644 packages/http-sdk/src/tx-http/tx-http.service.ts rename {apps/deploy-web/src/services => packages/http-sdk/src}/user-http/user-http.service.ts (72%) create mode 100644 packages/http-sdk/tsconfig.build.json create mode 100644 packages/http-sdk/tsconfig.json diff --git a/apps/api/package.json b/apps/api/package.json index d406fbd84..f500fbeae 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -50,7 +50,7 @@ "@opentelemetry/sdk-node": "^0.52.1", "@sentry/node": "^7.55.2", "@supercharge/promise-pool": "^3.2.0", - "axios": "^0.27.2", + "axios": "^1.7.2", "commander": "^12.1.0", "cosmjs-types": "^0.9.0", "date-fns": "^2.29.2", diff --git a/apps/api/src/billing/controllers/wallet/wallet.controller.ts b/apps/api/src/billing/controllers/wallet/wallet.controller.ts index 4573ef2d3..99f994347 100644 --- a/apps/api/src/billing/controllers/wallet/wallet.controller.ts +++ b/apps/api/src/billing/controllers/wallet/wallet.controller.ts @@ -11,6 +11,7 @@ import { ManagedUserWalletService, WalletInitializerService } from "@src/billing import { TxSignerService } from "@src/billing/services/tx-signer/tx-signer.service"; import { WithTransaction } from "@src/core/services"; +// TODO: authorize endpoints below @singleton() export class WalletController { constructor( diff --git a/apps/api/src/db/dbConnection.ts b/apps/api/src/db/dbConnection.ts index e6246361d..147972eab 100644 --- a/apps/api/src/db/dbConnection.ts +++ b/apps/api/src/db/dbConnection.ts @@ -27,11 +27,13 @@ if (!csMap[env.Network]) { } const logger = new PostgresLoggerService({ orm: "sequelize" }); +const logging = (msg: string) => logger.write(msg); pg.defaults.parseInt8 = true; export const chainDb = new Sequelize(csMap[env.Network], { dialectModule: pg, - logging: (msg: string) => logger.write(msg), + logging, + logQueryParameters: true, transactionType: DbTransaction.TYPES.IMMEDIATE, define: { timestamps: false, @@ -47,7 +49,8 @@ export const chainDbs: { [key: string]: Sequelize } = Object.keys(chainDefinitio ...obj, [chain]: new Sequelize(chainDefinitions[chain].connectionString, { dialectModule: pg, - logging: (msg: string) => logger.write(msg), + logging, + logQueryParameters: true, repositoryMode: true, transactionType: DbTransaction.TYPES.IMMEDIATE, define: { @@ -62,7 +65,8 @@ export const chainDbs: { [key: string]: Sequelize } = Object.keys(chainDefinitio export const userDb = new Sequelize(env.UserDatabaseCS, { dialectModule: pg, - logging: (msg: string) => logger.write(msg), + logging, + logQueryParameters: true, transactionType: DbTransaction.TYPES.IMMEDIATE, define: { timestamps: false, diff --git a/apps/deploy-web/package.json b/apps/deploy-web/package.json index 61f91d752..1247358f5 100644 --- a/apps/deploy-web/package.json +++ b/apps/deploy-web/package.json @@ -17,8 +17,8 @@ "dependencies": { "@akashnetwork/akash-api": "^1.3.0", "@akashnetwork/akashjs": "^0.10.0", - "@akashnetwork/ui": "*", "@akashnetwork/http-sdk": "*", + "@akashnetwork/ui": "*", "@auth0/nextjs-auth0": "^3.5.0", "@chain-registry/types": "^0.41.3", "@cosmjs/encoding": "^0.32.4", @@ -52,7 +52,7 @@ "@tanstack/react-table": "^8.13.2", "@textea/json-viewer": "^3.0.0", "auth0": "^4.3.1", - "axios": "^0.27.2", + "axios": "^1.7.2", "chain-registry": "^1.20.0", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", diff --git a/apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx b/apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx index f5223154f..c10356825 100644 --- a/apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx +++ b/apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx @@ -1,5 +1,6 @@ "use client"; import React, { useEffect, useMemo, useRef, useState } from "react"; +import type { TxOutput } from "@akashnetwork/http-sdk"; import { Snackbar } from "@akashnetwork/ui/components"; import { EncodeObject } from "@cosmjs/proto-signing"; import { SigningStargateClient } from "@cosmjs/stargate"; @@ -18,7 +19,7 @@ import { useUsdcDenom } from "@src/hooks/useDenom"; import { useManagedWallet } from "@src/hooks/useManagedWallet"; import { getSelectedNetwork, useSelectedNetwork } from "@src/hooks/useSelectedNetwork"; import { useWhen } from "@src/hooks/useWhen"; -import { txHttpService, TxOutput } from "@src/services/tx-http/tx-http.service"; +import { txHttpService } from "@src/services/http/http.service"; import { AnalyticsEvents } from "@src/utils/analytics"; import { STATS_APP_URL, uAktDenom } from "@src/utils/constants"; import { customRegistry } from "@src/utils/customRegistry"; diff --git a/apps/deploy-web/src/pages/api/auth/[...auth0].ts b/apps/deploy-web/src/pages/api/auth/[...auth0].ts index bf9995e5f..cde995f80 100644 --- a/apps/deploy-web/src/pages/api/auth/[...auth0].ts +++ b/apps/deploy-web/src/pages/api/auth/[...auth0].ts @@ -1,6 +1,6 @@ // pages/api/auth/[...auth0].js import { handleAuth, handleLogin, handleProfile } from "@auth0/nextjs-auth0"; -import axios, { AxiosRequestHeaders } from "axios"; +import axios, { AxiosHeaders } from "axios"; import type { NextApiRequest, NextApiResponse } from "next"; import { BASE_API_MAINNET_URL } from "@src/utils/constants"; @@ -22,14 +22,14 @@ export default handleAuth({ try { // TODO: Fix for console const user_metadata = session.user["https://console.akash.network/user_metadata"]; - const headers: AxiosRequestHeaders = { + const headers = new AxiosHeaders({ Authorization: `Bearer ${session.accessToken}` - }; + }); const anonymousId = req.headers["x-anonymous-user-id"]; if (anonymousId) { - headers["X-ANONYMOUS-USER-ID"] = anonymousId as string; + headers.set("x-anonymous-user-id", anonymousId); } const userSettings = await axios.post( @@ -41,7 +41,7 @@ export default handleAuth({ subscribedToNewsletter: user_metadata?.subscribedToNewsletter === "true" }, { - headers + headers: headers.toJSON() } ); diff --git a/apps/deploy-web/src/queries/useAnonymousUserQuery.ts b/apps/deploy-web/src/queries/useAnonymousUserQuery.ts index d5c3620ec..3e7145cdc 100644 --- a/apps/deploy-web/src/queries/useAnonymousUserQuery.ts +++ b/apps/deploy-web/src/queries/useAnonymousUserQuery.ts @@ -1,7 +1,7 @@ import { useState } from "react"; import { useWhen } from "@src/hooks/useWhen"; -import { userHttpService } from "@src/services/user-http/user-http.service"; +import { userHttpService } from "@src/services/http/http.service"; export interface UserOutput { id: string; diff --git a/apps/deploy-web/src/queries/useManagedWalletQuery.ts b/apps/deploy-web/src/queries/useManagedWalletQuery.ts index 8425be579..98ddb56c3 100644 --- a/apps/deploy-web/src/queries/useManagedWalletQuery.ts +++ b/apps/deploy-web/src/queries/useManagedWalletQuery.ts @@ -1,6 +1,6 @@ import { useMutation, useQuery, useQueryClient } from "react-query"; -import { managedWalletHttpService } from "@src/services/managed-wallet-http/managed-wallet-http.service"; +import { managedWalletHttpService } from "@src/services/http/http.service"; const MANAGED_WALLET = "MANAGED_WALLET"; diff --git a/apps/deploy-web/src/services/api-http/api-http.service.ts b/apps/deploy-web/src/services/api-http/api-http.service.ts deleted file mode 100644 index d3bc95bfe..000000000 --- a/apps/deploy-web/src/services/api-http/api-http.service.ts +++ /dev/null @@ -1,29 +0,0 @@ -import axios, { Axios, AxiosRequestConfig, AxiosResponse } from "axios"; - -import { BASE_API_URL } from "@src/utils/constants"; - -export interface ApiOutput { - data: T; -} - -export class ApiHttpService extends Axios { - constructor() { - const { headers, ...defaults } = axios.defaults; - super({ - ...defaults, - baseURL: BASE_API_URL - }); - } - - post>, D = any>(url: string, data?: D, config?: AxiosRequestConfig): Promise { - return super.post(url, data, config); - } - - get>, D = any>(url: string, config?: AxiosRequestConfig): Promise { - return super.get(url, config); - } - - protected extractData(response: ApiOutput>): AxiosResponse["data"] { - return response.data.data; - } -} diff --git a/apps/deploy-web/src/services/auth/auth-http.service.ts b/apps/deploy-web/src/services/auth/auth-http.service.ts index da7a0346d..394b1b070 100644 --- a/apps/deploy-web/src/services/auth/auth-http.service.ts +++ b/apps/deploy-web/src/services/auth/auth-http.service.ts @@ -1,6 +1,6 @@ import { HttpService } from "@akashnetwork/http-sdk"; import type { UserProfile } from "@auth0/nextjs-auth0/client"; -import { AxiosRequestHeaders } from "axios"; +import { AxiosHeaders } from "axios"; import { ANONYMOUS_USER_KEY } from "@src/utils/constants"; @@ -14,9 +14,12 @@ export class AuthHttpService extends HttpService { try { const user = localStorage.getItem(ANONYMOUS_USER_KEY); const anonymousUserId = user ? JSON.parse(user).id : undefined; - const headers: AxiosRequestHeaders = anonymousUserId ? { "X-ANONYMOUS-USER-ID": anonymousUserId } : {}; + const headers = new AxiosHeaders(); + if (anonymousUserId) { + headers.set("X-User-Id", anonymousUserId); + } - return this.extractData(await this.get(url, { headers })); + return this.extractData(await this.get(url, { headers: headers.toJSON() })); } catch (error) { console.warn("DEBUG error", error); throw error; diff --git a/apps/deploy-web/src/services/http/http.service.ts b/apps/deploy-web/src/services/http/http.service.ts new file mode 100644 index 000000000..71ff102fa --- /dev/null +++ b/apps/deploy-web/src/services/http/http.service.ts @@ -0,0 +1,10 @@ +import { ManagedWalletHttpService, TxHttpService, UserHttpService } from "@akashnetwork/http-sdk"; + +import { BASE_API_URL } from "@src/utils/constants"; +import { customRegistry } from "@src/utils/customRegistry"; + +const apiConfig = { baseURL: BASE_API_URL }; + +export const userHttpService = new UserHttpService(apiConfig); +export const txHttpService = new TxHttpService(customRegistry, apiConfig); +export const managedWalletHttpService = new ManagedWalletHttpService(apiConfig); diff --git a/apps/deploy-web/src/services/tx-http/tx-http.service.ts b/apps/deploy-web/src/services/tx-http/tx-http.service.ts deleted file mode 100644 index 2816197b8..000000000 --- a/apps/deploy-web/src/services/tx-http/tx-http.service.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { EncodeObject } from "@cosmjs/proto-signing/build/registry"; -import { DeliverTxResponse } from "@cosmjs/stargate"; - -import { ApiHttpService } from "@src/services/api-http/api-http.service"; -import { customRegistry } from "@src/utils/customRegistry"; - -export interface TxInput { - userId: string; - messages: EncodeObject[]; -} - -export type TxOutput = Pick; - -export class TxHttpService extends ApiHttpService { - async signAndBroadcastTx(input: TxInput) { - const messages = input.messages.map(m => ({ ...m, value: Buffer.from(customRegistry.encode(m)).toString("base64") })); - - return this.extractData( - await this.post("v1/tx", { - data: { - userId: input.userId, - messages: messages - } - }) - ); - } -} - -export const txHttpService = new TxHttpService(); diff --git a/apps/indexer/package.json b/apps/indexer/package.json index c416df26a..1aa3b8f05 100644 --- a/apps/indexer/package.json +++ b/apps/indexer/package.json @@ -31,7 +31,7 @@ "@cosmjs/stargate": "^0.32.4", "@sentry/node": "^7.52.0", "async": "^3.2.4", - "axios": "^0.27.2", + "axios": "^1.7.2", "cosmjs-types": "^0.9.0", "date-fns": "^2.29.2", "date-fns-tz": "^1.3.6", diff --git a/apps/provider-proxy/package.json b/apps/provider-proxy/package.json index 925c8cab7..726bc3386 100644 --- a/apps/provider-proxy/package.json +++ b/apps/provider-proxy/package.json @@ -13,7 +13,7 @@ "dev": "npm run start" }, "dependencies": { - "axios": "^1.3.0", + "axios": "^1.7.2", "cors": "^2.8.5", "express": "^4.18.2", "node-fetch": "^2.6.9", diff --git a/apps/stats-web/package.json b/apps/stats-web/package.json index 284ce0529..9d1bf009a 100644 --- a/apps/stats-web/package.json +++ b/apps/stats-web/package.json @@ -18,7 +18,7 @@ "@radix-ui/react-slot": "^1.0.2", "@tanstack/react-table": "^8.11.2", "@textea/json-viewer": "^3.2.3", - "axios": "^1.6.1", + "axios": "^1.7.2", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", "geist": "^1.3.0", diff --git a/package-lock.json b/package-lock.json index 903694e5a..1cebb8585 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,7 +49,7 @@ "@opentelemetry/sdk-node": "^0.52.1", "@sentry/node": "^7.55.2", "@supercharge/promise-pool": "^3.2.0", - "axios": "^0.27.2", + "axios": "^1.7.2", "commander": "^12.1.0", "cosmjs-types": "^0.9.0", "date-fns": "^2.29.2", @@ -159,6 +159,16 @@ "xstream": "^11.14.0" } }, + "apps/api/node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "apps/api/node_modules/on-exit-leak-free": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", @@ -296,7 +306,7 @@ "@tanstack/react-table": "^8.13.2", "@textea/json-viewer": "^3.0.0", "auth0": "^4.3.1", - "axios": "^0.27.2", + "axios": "^1.7.2", "chain-registry": "^1.20.0", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", @@ -430,6 +440,16 @@ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", "dev": true }, + "apps/deploy-web/node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "apps/indexer": { "name": "console-indexer", "version": "1.9.1", @@ -444,7 +464,7 @@ "@cosmjs/stargate": "^0.32.4", "@sentry/node": "^7.52.0", "async": "^3.2.4", - "axios": "^0.27.2", + "axios": "^1.7.2", "cosmjs-types": "^0.9.0", "date-fns": "^2.29.2", "date-fns-tz": "^1.3.6", @@ -544,6 +564,16 @@ "xstream": "^11.14.0" } }, + "apps/indexer/node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "apps/indexer/node_modules/reflect-metadata": { "version": "0.1.14", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", @@ -665,7 +695,7 @@ "version": "1.0.7", "license": "Apache-2.0", "dependencies": { - "axios": "^1.3.0", + "axios": "^1.7.2", "cors": "^2.8.5", "express": "^4.18.2", "node-fetch": "^2.6.9", @@ -715,7 +745,7 @@ "@radix-ui/react-slot": "^1.0.2", "@tanstack/react-table": "^8.11.2", "@textea/json-viewer": "^3.2.3", - "axios": "^1.6.1", + "axios": "^1.7.2", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", "geist": "^1.3.0", @@ -4022,7 +4052,6 @@ "version": "0.32.4", "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.32.4.tgz", "integrity": "sha512-QdyQDbezvdRI4xxSlyM1rSVBO2st5sqtbEIl3IX03uJ7YiZIQHyv6vaHVf1V4mapusCqguiHJzm4N4gsFdLBbQ==", - "license": "Apache-2.0", "dependencies": { "@cosmjs/amino": "^0.32.4", "@cosmjs/crypto": "^0.32.4", @@ -19410,9 +19439,9 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "node_modules/@types/lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", "dev": true }, "node_modules/@types/long": { @@ -45643,7 +45672,51 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "axios": "^1.7.2" + "axios": "^1.7.2", + "lodash": "^4.17.21" + }, + "devDependencies": { + "@cosmjs/proto-signing": "^0.32.4", + "@cosmjs/stargate": "^0.32.4", + "@types/lodash": "^4.17.7" + } + }, + "packages/http-sdk/node_modules/@cosmjs/encoding": { + "version": "0.32.4", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.32.4.tgz", + "integrity": "sha512-tjvaEy6ZGxJchiizzTn7HVRiyTg1i4CObRRaTRPknm5EalE13SV+TCHq38gIDfyUeden4fCuaBVEdBR5+ti7Hw==", + "dev": true, + "dependencies": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "packages/http-sdk/node_modules/@cosmjs/math": { + "version": "0.32.4", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.32.4.tgz", + "integrity": "sha512-++dqq2TJkoB8zsPVYCvrt88oJWsy1vMOuSOKcdlnXuOA/ASheTJuYy4+oZlTQ3Fr8eALDLGGPhJI02W2HyAQaw==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.0" + } + }, + "packages/http-sdk/node_modules/@cosmjs/stargate": { + "version": "0.32.4", + "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.32.4.tgz", + "integrity": "sha512-usj08LxBSsPRq9sbpCeVdyLx2guEcOHfJS9mHGCLCXpdAPEIEQEtWLDpEUc0LEhWOx6+k/ChXTc5NpFkdrtGUQ==", + "dev": true, + "dependencies": { + "@confio/ics23": "^0.6.8", + "@cosmjs/amino": "^0.32.4", + "@cosmjs/encoding": "^0.32.4", + "@cosmjs/math": "^0.32.4", + "@cosmjs/proto-signing": "^0.32.4", + "@cosmjs/stream": "^0.32.4", + "@cosmjs/tendermint-rpc": "^0.32.4", + "@cosmjs/utils": "^0.32.4", + "cosmjs-types": "^0.9.0", + "xstream": "^11.14.0" } }, "packages/http-sdk/node_modules/axios": { diff --git a/packages/http-sdk/package.json b/packages/http-sdk/package.json index 0200ad12f..d619256e5 100644 --- a/packages/http-sdk/package.json +++ b/packages/http-sdk/package.json @@ -11,6 +11,12 @@ "lint": "eslint ." }, "dependencies": { - "axios": "^1.7.2" + "axios": "^1.7.2", + "lodash": "^4.17.21" + }, + "devDependencies": { + "@cosmjs/proto-signing": "^0.32.4", + "@cosmjs/stargate": "^0.32.4", + "@types/lodash": "^4.17.7" } } diff --git a/packages/http-sdk/src/api-http/api-http.service.ts b/packages/http-sdk/src/api-http/api-http.service.ts new file mode 100644 index 000000000..5aca315af --- /dev/null +++ b/packages/http-sdk/src/api-http/api-http.service.ts @@ -0,0 +1,24 @@ +import { HttpService } from "@akashnetwork/http-sdk"; +import { AxiosRequestConfig, AxiosResponse } from "axios"; + +export interface ApiOutput { + data: T; +} + +export class ApiHttpService extends HttpService { + constructor(config?: AxiosRequestConfig) { + super(config); + } + + post>, D = any>(url: string, data?: D, config?: AxiosRequestConfig): Promise { + return super.post(url, data, config); + } + + get>, D = any>(url: string, config?: AxiosRequestConfig): Promise { + return super.get(url, config); + } + + protected extractApiData(response: ApiOutput>): AxiosResponse["data"] { + return this.extractData(response.data); + } +} diff --git a/packages/http-sdk/src/index.ts b/packages/http-sdk/src/index.ts index c4f89d524..7b2d7afa6 100644 --- a/packages/http-sdk/src/index.ts +++ b/packages/http-sdk/src/index.ts @@ -1,2 +1,6 @@ export * from "./http/http.service"; export * from "./allowance/allowance-http.service"; +export * from "./api-http/api-http.service"; +export * from "./tx-http/tx-http.service"; +export * from "./managed-wallet-http/managed-wallet-http.service"; +export * from "./user-http/user-http.service"; diff --git a/apps/deploy-web/src/services/managed-wallet-http/managed-wallet-http.service.ts b/packages/http-sdk/src/managed-wallet-http/managed-wallet-http.service.ts similarity index 59% rename from apps/deploy-web/src/services/managed-wallet-http/managed-wallet-http.service.ts rename to packages/http-sdk/src/managed-wallet-http/managed-wallet-http.service.ts index 813d0beba..16d45ba3f 100644 --- a/apps/deploy-web/src/services/managed-wallet-http/managed-wallet-http.service.ts +++ b/packages/http-sdk/src/managed-wallet-http/managed-wallet-http.service.ts @@ -1,4 +1,4 @@ -import { ApiHttpService } from "@src/services/api-http/api-http.service"; +import { ApiHttpService } from "../api-http/api-http.service"; export interface ApiWalletOutput { id: string; @@ -9,11 +9,11 @@ export interface ApiWalletOutput { export class ManagedWalletHttpService extends ApiHttpService { async createWallet(userId: string) { - return this.addWalletEssentials(this.extractData(await this.post("v1/wallets", { data: { userId } }))); + return this.addWalletEssentials(this.extractApiData(await this.post("v1/wallets", { data: { userId } }))); } async getWallet(userId: string) { - const [wallet] = this.extractData(await this.get("v1/wallets", { params: { userId } })); + const [wallet] = this.extractApiData(await this.get("v1/wallets", { params: { userId } })); return wallet && this.addWalletEssentials(wallet); } @@ -26,5 +26,3 @@ export class ManagedWalletHttpService extends ApiHttpService { }; } } - -export const managedWalletHttpService = new ManagedWalletHttpService(); diff --git a/packages/http-sdk/src/tx-http/tx-http.service.ts b/packages/http-sdk/src/tx-http/tx-http.service.ts new file mode 100644 index 000000000..4b54ecfad --- /dev/null +++ b/packages/http-sdk/src/tx-http/tx-http.service.ts @@ -0,0 +1,33 @@ +import { ApiHttpService } from "@akashnetwork/http-sdk"; +import type { Registry } from "@cosmjs/proto-signing"; +import type { EncodeObject } from "@cosmjs/proto-signing/build/registry"; +import type { DeliverTxResponse } from "@cosmjs/stargate"; +import { AxiosRequestConfig } from "axios"; + +export interface TxInput { + userId: string; + messages: EncodeObject[]; +} + +export type TxOutput = Pick; + +export class TxHttpService extends ApiHttpService { + constructor( + private readonly registry: Registry, + config?: AxiosRequestConfig + ) { + super(config); + } + async signAndBroadcastTx(input: TxInput) { + const messages = input.messages.map(m => ({ ...m, value: Buffer.from(this.registry.encode(m)).toString("base64") })); + + return this.extractApiData( + await this.post("v1/tx", { + data: { + userId: input.userId, + messages: messages + } + }) + ); + } +} diff --git a/apps/deploy-web/src/services/user-http/user-http.service.ts b/packages/http-sdk/src/user-http/user-http.service.ts similarity index 72% rename from apps/deploy-web/src/services/user-http/user-http.service.ts rename to packages/http-sdk/src/user-http/user-http.service.ts index ec48cc948..ccd6c7ab3 100644 --- a/apps/deploy-web/src/services/user-http/user-http.service.ts +++ b/packages/http-sdk/src/user-http/user-http.service.ts @@ -1,7 +1,7 @@ +import { ApiHttpService } from "@akashnetwork/http-sdk"; +import { AxiosRequestConfig } from "axios"; import memoize from "lodash/memoize"; -import { ApiHttpService } from "@src/services/api-http/api-http.service"; - export interface UserOutput { id: string; userId?: string; @@ -17,8 +17,8 @@ export interface UserOutput { } export class UserHttpService extends ApiHttpService { - constructor() { - super(); + constructor(config?: AxiosRequestConfig) { + super(config); this.getOrCreateAnonymousUser = memoize(this.getOrCreateAnonymousUser.bind(this)); } @@ -27,12 +27,12 @@ export class UserHttpService extends ApiHttpService { } private async createAnonymousUser() { - return this.extractData(await this.post("/v1/anonymous-users")); + return this.extractApiData(await this.post("/v1/anonymous-users")); } private async getAnonymousUser(id: string) { try { - return this.extractData(await this.get(`/v1/anonymous-users/${id}`)); + return this.extractApiData(await this.get(`/v1/anonymous-users/${id}`)); } catch (error) { if (error.response?.status === 404) { return this.createAnonymousUser(); @@ -42,5 +42,3 @@ export class UserHttpService extends ApiHttpService { } } } - -export const userHttpService = new UserHttpService(); diff --git a/packages/http-sdk/tsconfig.build.json b/packages/http-sdk/tsconfig.build.json new file mode 100644 index 000000000..306ea8d76 --- /dev/null +++ b/packages/http-sdk/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "noImplicitAny": true, + "paths": { + "@src/*": ["./src/*"], + "@test/*": ["./test/*"] + } + }, + "extends": "@akashnetwork/dev-config/tsconfig.base-node.json" +} diff --git a/packages/http-sdk/tsconfig.json b/packages/http-sdk/tsconfig.json new file mode 100644 index 000000000..579446f28 --- /dev/null +++ b/packages/http-sdk/tsconfig.json @@ -0,0 +1,5 @@ +{ + "exclude": ["node_modules", "dist", "**/*spec.ts"], + "extends": "./tsconfig.build.json", + "include": ["src/**/*"] +}