From 28bd7472749a0acbf83e4b1e6f5cc754ec881894 Mon Sep 17 00:00:00 2001 From: Redm4x Date: Wed, 16 Aug 2023 11:06:55 -0400 Subject: [PATCH 1/7] Remove deprecated code --- README.md | 1 - api/src/providers/userDataProvider.ts | 15 +-- api/src/routers/dashboardRouter.ts | 2 +- api/src/routers/userRouter.ts | 4 +- deploy-web/src/pages/api/auth/[...auth0].ts | 3 +- deploy-web/src/types/alert.ts | 44 --------- shared/dbSchemas/index.ts | 26 +----- shared/dbSchemas/user/alertEvent.ts | 29 ------ shared/dbSchemas/user/alertEventMessage.ts | 26 ------ shared/dbSchemas/user/alertMonitoredValue.ts | 16 ---- shared/dbSchemas/user/alertTrigger.ts | 15 --- .../dbSchemas/user/alertTriggerCondition.ts | 13 --- shared/dbSchemas/user/index.ts | 6 -- shared/dbSchemas/user/userAlert.ts | 32 ------- shared/dbSchemas/user/userSetting.ts | 9 +- shared/providers/monitoredValueProvider.ts | 92 ------------------- 16 files changed, 10 insertions(+), 323 deletions(-) delete mode 100644 deploy-web/src/types/alert.ts delete mode 100644 shared/dbSchemas/user/alertEvent.ts delete mode 100644 shared/dbSchemas/user/alertEventMessage.ts delete mode 100644 shared/dbSchemas/user/alertMonitoredValue.ts delete mode 100644 shared/dbSchemas/user/alertTrigger.ts delete mode 100644 shared/dbSchemas/user/alertTriggerCondition.ts delete mode 100644 shared/dbSchemas/user/userAlert.ts delete mode 100644 shared/providers/monitoredValueProvider.ts diff --git a/README.md b/README.md index ef2b7c3fa..6a7620f50 100644 --- a/README.md +++ b/README.md @@ -394,4 +394,3 @@ Created when a user "favorite" a template |youtubeUsername|varchar |twitterUsername|varchar |githubUsername|varchar -|accountType|varchar|`CLOUDMOS` or `BLOCKSPY` diff --git a/api/src/providers/userDataProvider.ts b/api/src/providers/userDataProvider.ts index 29888752a..55d953204 100644 --- a/api/src/providers/userDataProvider.ts +++ b/api/src/providers/userDataProvider.ts @@ -7,7 +7,7 @@ function randomIntFromInterval(min: number, max: number) { } export async function checkUsernameAvailable(username: string, dbTransaction?: Transaction): Promise { - const existingUser = await UserSetting.findOne({ where: { username: username, accountType: "cloudmos" }, transaction: dbTransaction }); + const existingUser = await UserSetting.findOne({ where: { username: username }, transaction: dbTransaction }); return !existingUser; } @@ -60,14 +60,7 @@ export async function updateSettings( await settings.save(); } -export async function getSettingsOrInit( - userId: string, - wantedUsername: string, - email: string, - emailVerified: boolean, - subscribedToNewsletter: boolean, - accountType: string = "cloudmos" -) { +export async function getSettingsOrInit(userId: string, wantedUsername: string, email: string, emailVerified: boolean, subscribedToNewsletter: boolean) { let [userSettings, created] = await UserSetting.findCreateFind({ where: { userId: userId }, defaults: { @@ -76,8 +69,7 @@ export async function getSettingsOrInit( email: email, emailVerified: emailVerified, stripeCustomerId: null, - subscribedToNewsletter: subscribedToNewsletter, - accountType: accountType + subscribedToNewsletter: subscribedToNewsletter } }); @@ -86,7 +78,6 @@ export async function getSettingsOrInit( } else if (userSettings.email !== email || userSettings.emailVerified !== emailVerified) { userSettings.email = email; userSettings.emailVerified = emailVerified; - userSettings.accountType = accountType; await userSettings.save(); } diff --git a/api/src/routers/dashboardRouter.ts b/api/src/routers/dashboardRouter.ts index 6029db076..9cce63240 100644 --- a/api/src/routers/dashboardRouter.ts +++ b/api/src/routers/dashboardRouter.ts @@ -10,7 +10,7 @@ dashboardRouter.use(privateMiddleware); dashboardRouter.get( "/stats", asyncHandler(async (req, res) => { - const userCountRequest = UserSetting.count({ where: { accountType: "cloudmos" } }); + const userCountRequest = UserSetting.count(); const publicTemplateCountRequest = Template.count({ where: { isPublic: true } }); diff --git a/api/src/routers/userRouter.ts b/api/src/routers/userRouter.ts index 263c4e8df..b62805e1e 100644 --- a/api/src/routers/userRouter.ts +++ b/api/src/routers/userRouter.ts @@ -143,9 +143,9 @@ userRouter.post( express.json(), asyncHandler(async (req: JWTRequest, res) => { const userId = req.auth?.sub; - const { wantedUsername, email, emailVerified, subscribedToNewsletter, accountType } = req.body; + const { wantedUsername, email, emailVerified, subscribedToNewsletter } = req.body; - const settings = await getSettingsOrInit(userId, wantedUsername, email, !!emailVerified, subscribedToNewsletter, accountType); + const settings = await getSettingsOrInit(userId, wantedUsername, email, !!emailVerified, subscribedToNewsletter); res.send(settings); }) diff --git a/deploy-web/src/pages/api/auth/[...auth0].ts b/deploy-web/src/pages/api/auth/[...auth0].ts index ee880232f..337c29bc0 100644 --- a/deploy-web/src/pages/api/auth/[...auth0].ts +++ b/deploy-web/src/pages/api/auth/[...auth0].ts @@ -26,8 +26,7 @@ export default handleAuth({ wantedUsername: session.user.nickname, email: session.user.email, emailVerified: session.user.email_verified, - subscribedToNewsletter: user_metadata?.subscribedToNewsletter === "true", - accountType: "cloudmos" + subscribedToNewsletter: user_metadata?.subscribedToNewsletter === "true" }, { headers: { diff --git a/deploy-web/src/types/alert.ts b/deploy-web/src/types/alert.ts deleted file mode 100644 index 9c94210d5..000000000 --- a/deploy-web/src/types/alert.ts +++ /dev/null @@ -1,44 +0,0 @@ -export interface IUserAlert { - id: string; - name: string; - type: string; - chain: string; - eventCount: number; - enabled: boolean; - msgType: string; - createdOn: string; -} - -export interface IUserEditAlert extends IUserAlert { - userId: string; - chain: string; - isRecurring: boolean; - cooldown: string; - note: string; - channels: string; - webhookUrl: string; - alertTriggers: IAlertTrigger[]; -} - -export interface IAlertEvent { - id: string; - eventDate: string; - txHash?: string; - height?: number; -} - -export interface IAlertTrigger { - id: string; - alertId: string; - msgType: string; - alertTriggerConditions: IAlertTriggerCondition[]; -} - -export interface IAlertTriggerCondition { - id: string; - alertTriggerId: string; - key: string; - value: string; - operator: string; - unit?: string; -} diff --git a/shared/dbSchemas/index.ts b/shared/dbSchemas/index.ts index efbd81523..57778e759 100644 --- a/shared/dbSchemas/index.ts +++ b/shared/dbSchemas/index.ts @@ -1,18 +1,7 @@ import { activeChain, chainDefinitions } from "../chainDefinitions"; import { Model, ModelCtor } from "sequelize-typescript"; import { AddressReference, Block as BaseBlock, Day, Message as BaseMessage, Transaction, Validator, MonitoredValue } from "./base"; -import { - UserSetting, - Template, - TemplateFavorite, - UserAddressName, - UserAlert, - AlertEvent, - AlertTrigger, - AlertTriggerCondition, - AlertEventMessage, - AlertMonitoredValue -} from "./user"; +import { UserSetting, Template, TemplateFavorite, UserAddressName } from "./user"; function getFilteredBaseModel(): ModelCtor>[] { let models: ModelCtor>[] = baseModels; @@ -41,17 +30,6 @@ export function getChainModels(chainName: string) { } export const chainModels = [...getFilteredBaseModel(), ...(activeChain.customModels ?? [])]; -export const userModels: ModelCtor>[] = [ - UserSetting, - Template, - TemplateFavorite, - UserAddressName, - UserAlert, - AlertEvent, - AlertEventMessage, - AlertTrigger, - AlertTriggerCondition, - AlertMonitoredValue -]; +export const userModels: ModelCtor>[] = [UserSetting, Template, TemplateFavorite, UserAddressName]; export const Block = activeChain.customBlockModel || BaseBlock; export const Message = activeChain.customMessageModel || BaseMessage; diff --git a/shared/dbSchemas/user/alertEvent.ts b/shared/dbSchemas/user/alertEvent.ts deleted file mode 100644 index 22f9f25a1..000000000 --- a/shared/dbSchemas/user/alertEvent.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { DataTypes, UUIDV4 } from "sequelize"; -import { - BelongsTo, - Column, - Default, - Model, - PrimaryKey, - Table, -} from "sequelize-typescript"; -import { Required } from "../decorators/requiredDecorator"; -import { UserAlert } from "./userAlert"; -import { UserSetting } from "./userSetting"; - -@Table({ modelName: "alertEvent", indexes: [{ fields: ["userId"] }] }) -export class AlertEvent extends Model { - @Required @PrimaryKey @Default(UUIDV4) @Column(DataTypes.UUID) id: string; - @Required @Column userId: string; - @Required @Column(DataTypes.UUID) alertId: string; - @Column msgId?: string; - @Column txHash?: string; - @Column height?: number; - @Required @Column eventDate: Date; - @Required @Column createdDate: Date; - @Column(DataTypes.TEXT) payload?: string; - - @BelongsTo(() => UserAlert, "alertId") userAlert: UserAlert; - @BelongsTo(() => UserSetting, { foreignKey: "userId", targetKey: "userId" }) - userSetting: UserSetting; -} diff --git a/shared/dbSchemas/user/alertEventMessage.ts b/shared/dbSchemas/user/alertEventMessage.ts deleted file mode 100644 index a035927a5..000000000 --- a/shared/dbSchemas/user/alertEventMessage.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { DataTypes, UUIDV4 } from "sequelize"; -import { - BelongsTo, - Column, - Default, - Model, - PrimaryKey, - Table, -} from "sequelize-typescript"; -import { Required } from "../decorators/requiredDecorator"; -import { AlertEvent } from "./alertEvent"; - -@Table({ - modelName: "alertEventMessage", - indexes: [{ fields: ["alertEventId"] }], -}) -export class AlertEventMessage extends Model { - @Required @PrimaryKey @Default(UUIDV4) @Column(DataTypes.UUID) id: string; - @Required @Column(DataTypes.UUID) alertEventId: string; - @Column sentDate?: Date; - @Column error?: string; - @Column channel: string; - @Column retryCount?: number; - - @BelongsTo(() => AlertEvent, "alertEventId") alertEvent: AlertEvent; -} diff --git a/shared/dbSchemas/user/alertMonitoredValue.ts b/shared/dbSchemas/user/alertMonitoredValue.ts deleted file mode 100644 index b2389f958..000000000 --- a/shared/dbSchemas/user/alertMonitoredValue.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DataTypes, UUIDV4 } from "sequelize"; -import { BelongsTo, Column, Default, Model, PrimaryKey, Table } from "sequelize-typescript"; -import { Required } from "../decorators/requiredDecorator"; -import { UserAlert } from "./userAlert"; - -@Table({ modelName: "alertMonitoredValue" }) -export class AlertMonitoredValue extends Model { - @Required @PrimaryKey @Default(UUIDV4) @Column(DataTypes.UUID) id: string; - @Required @Column(DataTypes.UUID) alertId: string; - @Required @Column target: string; - @Required @Column operator: string; - @Required @Column value: string; - @Required @Default(false) @Column isMatching: boolean; - - @BelongsTo(() => UserAlert, "alertId") userAlert: UserAlert; -} diff --git a/shared/dbSchemas/user/alertTrigger.ts b/shared/dbSchemas/user/alertTrigger.ts deleted file mode 100644 index 927879cce..000000000 --- a/shared/dbSchemas/user/alertTrigger.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { DataTypes, UUIDV4 } from "sequelize"; -import { BelongsTo, Column, Default, HasMany, Model, PrimaryKey, Table } from "sequelize-typescript"; -import { Required } from "../decorators/requiredDecorator"; -import { AlertTriggerCondition } from "./alertTriggerCondition"; -import { UserAlert } from "./userAlert"; - -@Table({ modelName: "alertTrigger", indexes: [{ fields: ["alertId"] }] }) -export class AlertTrigger extends Model { - @Required @PrimaryKey @Default(UUIDV4) @Column(DataTypes.UUID) id: string; - @Required @Column(DataTypes.UUID) alertId: string; - @Required @Column msgType: string; - - @BelongsTo(() => UserAlert, "alertId") userAlert: UserAlert; - @HasMany(() => AlertTriggerCondition, "alertTriggerId") alertTriggerConditions: AlertTriggerCondition[]; -} diff --git a/shared/dbSchemas/user/alertTriggerCondition.ts b/shared/dbSchemas/user/alertTriggerCondition.ts deleted file mode 100644 index 6b3c7704e..000000000 --- a/shared/dbSchemas/user/alertTriggerCondition.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { DataTypes, UUIDV4 } from "sequelize"; -import { Column, Default, Model, PrimaryKey, Table } from "sequelize-typescript"; -import { Required } from "../decorators/requiredDecorator"; - -@Table({ modelName: "alertTriggerCondition", indexes: [{ fields: ["alertTriggerId"] }] }) -export class AlertTriggerCondition extends Model { - @Required @PrimaryKey @Default(UUIDV4) @Column(DataTypes.UUID) id: string; - @Required @Column(DataTypes.UUID) alertTriggerId: string; - @Required @Column key: string; - @Required @Column operator: string; - @Required @Column value: string; - @Column unit?: string; -} diff --git a/shared/dbSchemas/user/index.ts b/shared/dbSchemas/user/index.ts index d708aadc8..79e7b6439 100644 --- a/shared/dbSchemas/user/index.ts +++ b/shared/dbSchemas/user/index.ts @@ -2,9 +2,3 @@ export { Template } from "./template"; export { TemplateFavorite } from "./templateFavorite"; export { UserAddressName } from "./userAddressName"; export { UserSetting } from "./userSetting"; -export { UserAlert } from "./userAlert"; -export { AlertEventMessage } from "./alertEventMessage"; -export { AlertEvent } from "./alertEvent"; -export { AlertTrigger } from "./alertTrigger"; -export { AlertTriggerCondition } from "./alertTriggerCondition"; -export { AlertMonitoredValue } from "./alertMonitoredValue"; diff --git a/shared/dbSchemas/user/userAlert.ts b/shared/dbSchemas/user/userAlert.ts deleted file mode 100644 index 593e44d82..000000000 --- a/shared/dbSchemas/user/userAlert.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { DataTypes, UUIDV4 } from "sequelize"; -import { BelongsTo, Column, Default, HasMany, Model, PrimaryKey, Table } from "sequelize-typescript"; -import { Required } from "../decorators/requiredDecorator"; -import { AlertEvent } from "./alertEvent"; -import { AlertMonitoredValue } from "./alertMonitoredValue"; -import { AlertTrigger } from "./alertTrigger"; - -@Table({ modelName: "userAlert", indexes: [{ fields: ["userId"] }] }) -export class UserAlert extends Model { - @Required @PrimaryKey @Default(UUIDV4) @Column(DataTypes.UUID) id: string; - @Required @Column userId: string; - @Required @Column name: string; - @Required @Column chain: string; - @Required @Column type: string; - @Required @Column isRecurring: boolean; - @Column cooldown: string; - @Required @Column channels: string; - @Column note?: string; - @Required @Default(false) @Column enabled: boolean; - @Required @Default(false) @Column isDeleted: boolean; - @Column deletedOn?: Date; - @Column(DataTypes.UUID) oldVersionOfId?: string; - @Required @Column createdOn: Date; - @Column updatedOn?: Date; - @Required @Default(0) @Column eventCount: number; - @Column webhookUrl?: string; - - @BelongsTo(() => UserAlert, { foreignKey: "oldVersionOfId", targetKey: "id" }) oldVersionOf: UserAlert; - @HasMany(() => AlertTrigger, "alertId") alertTriggers: AlertTrigger[]; - @HasMany(() => AlertMonitoredValue, "alertId") alertMonitoredValues: AlertMonitoredValue[]; - @HasMany(() => AlertEvent, "alertId") alertEvents: AlertEvent[]; -} diff --git a/shared/dbSchemas/user/userSetting.ts b/shared/dbSchemas/user/userSetting.ts index 700f25c76..24f8f8bb4 100644 --- a/shared/dbSchemas/user/userSetting.ts +++ b/shared/dbSchemas/user/userSetting.ts @@ -2,13 +2,12 @@ import { Column, Default, HasMany, Model, PrimaryKey, Table } from "sequelize-ty import { DataTypes, UUIDV4 } from "sequelize"; import { Required } from "../decorators/requiredDecorator"; import { Template } from "./template"; -import { UserAlert } from "./userAlert"; @Table({ modelName: "userSetting", indexes: [ { unique: true, fields: ["userId"] }, - { unique: true, fields: ["username", "accountType"] } + { unique: true, fields: ["username"] } ] }) export class UserSetting extends Model { @@ -23,12 +22,6 @@ export class UserSetting extends Model { @Column youtubeUsername?: string; @Column twitterUsername?: string; @Column githubUsername?: string; - // Temporary field to identify the type of account between cloudmos and blockspy.io - @Required - @Default("cloudmos") - @Column - accountType: string; @HasMany(() => Template, { foreignKey: "userId", sourceKey: "userId" }) templates: Template[]; - @HasMany(() => UserAlert, { foreignKey: "userId", sourceKey: "userId" }) userAlerts: UserAlert[]; } diff --git a/shared/providers/monitoredValueProvider.ts b/shared/providers/monitoredValueProvider.ts deleted file mode 100644 index 837778e1e..000000000 --- a/shared/providers/monitoredValueProvider.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { MonitoredValueTrackerType, NotificationTemplate } from "../"; -import { MonitoredValue } from "../dbSchemas/base"; -import { UserAlert, AlertMonitoredValue } from "../dbSchemas/user"; -import { Transaction as DbTransaction } from "sequelize"; -import { Sequelize } from "sequelize-typescript"; -// TEST CHANGES -export function getTargetFromConditions( - tracker: MonitoredValueTrackerType, - conditions: { - [key: string]: { - operator: string; - value: string; - }; - } -): string { - switch (tracker) { - case "AddressBalanceMonitor": - return conditions["address"].value; - case "DeploymentBalanceMonitor": - return `${conditions["owner"].value}/${conditions["dseq"].value}`; - default: - throw new Error(`Unknown tracker type: ${tracker}`); - } -} - -export function getConditionsFromTarget(tracker: MonitoredValueTrackerType, target: string): { key: string; value: string }[] { - switch (tracker) { - case "AddressBalanceMonitor": - return [ - { - key: "address", - value: target - } - ]; - case "DeploymentBalanceMonitor": - const [owner, dseq] = target.split("/"); - return [ - { key: "owner", value: owner }, - { key: "dseq", value: dseq } - ]; - default: - throw new Error(`Unknown tracker type: ${tracker}`); - } -} - -export async function createMonitoredValueIfNeeded(db: Sequelize, tracker: string, target: string) { - const monitoredValueRepository = db.getRepository(MonitoredValue); - await monitoredValueRepository.findOrCreate({ - defaults: { tracker: tracker, target: target }, - where: { - tracker: tracker, - target: target - } - }); -} - -export async function deleteMonitoredValueIfNoLongerNeeded( - db: Sequelize, - chain: string, - notifTemplate: NotificationTemplate, - target: string, - userDbTransaction: DbTransaction | undefined = undefined -) { - const otherAlert = await AlertMonitoredValue.findOne({ - where: { - target: target - }, - include: [ - { - model: UserAlert, - required: true, - where: { - chain: chain, - type: notifTemplate.code, - isDeleted: false, - enabled: true - } - } - ], - transaction: userDbTransaction - }); - - if (!otherAlert) { - const monitoredValueRepository = db.getRepository(MonitoredValue); - await monitoredValueRepository.destroy({ - where: { - tracker: notifTemplate.tracker, - target: target - } - }); - } -} From a9b8755164179084fc0c484da2d05b3cb57c0af7 Mon Sep 17 00:00:00 2001 From: Redm4x Date: Wed, 16 Aug 2023 11:19:34 -0400 Subject: [PATCH 2/7] Remove more deprecated code --- README.md | 2 +- .../deployment/DeploymentListRow.tsx | 14 -- .../DeploymentDetailTopBar.tsx | 14 -- deploy-web/src/pages/validators/[address].tsx | 1 - deploy-web/src/queries/queryKeys.ts | 2 - shared/alertTemplates/akash.ts | 92 ------------ shared/alertTemplates/cosmos.ts | 140 ------------------ shared/alertTemplates/index.ts | 42 ------ shared/alertTemplates/stargaze.ts | 74 --------- shared/index.ts | 3 - shared/msgSchemas/akashSchemas.ts | 93 ------------ shared/msgSchemas/cosmosSchemas.ts | 90 ----------- shared/msgSchemas/index.ts | 14 -- shared/msgSchemas/stargazeSchemas.ts | 39 ----- shared/propertyTypes.ts | 19 --- 15 files changed, 1 insertion(+), 638 deletions(-) delete mode 100644 shared/alertTemplates/akash.ts delete mode 100644 shared/alertTemplates/cosmos.ts delete mode 100644 shared/alertTemplates/index.ts delete mode 100644 shared/alertTemplates/stargaze.ts delete mode 100644 shared/index.ts delete mode 100644 shared/msgSchemas/akashSchemas.ts delete mode 100644 shared/msgSchemas/cosmosSchemas.ts delete mode 100644 shared/msgSchemas/index.ts delete mode 100644 shared/msgSchemas/stargazeSchemas.ts delete mode 100644 shared/propertyTypes.ts diff --git a/README.md b/README.md index 6a7620f50..a6a219c4d 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ The database schemas is defined using [sequelize-typescript](https://github.com/ - **base** - Tables which are cosmos generic and are used for every chains - **akash** - Tables which are akash specific (they are not created when initializing a database for another chain) -- **user** - Tables which are user specific. Contains tables for user settings, templates and alerts (BlockSpy specific) +- **user** - Tables which are user specific. Contains tables for user settings and templates ## Block |Column|Type|Note| diff --git a/deploy-web/src/components/deployment/DeploymentListRow.tsx b/deploy-web/src/components/deployment/DeploymentListRow.tsx index bca64fbd8..232700385 100644 --- a/deploy-web/src/components/deployment/DeploymentListRow.tsx +++ b/deploy-web/src/components/deployment/DeploymentListRow.tsx @@ -197,19 +197,6 @@ export const DeploymentListRow: React.FunctionComponent = ({ deployment, router.push(url); }; - // TODO Alerts - // const onSetAlert = () => { - // window.open( - // UrlService.alertsCreate(null, "akash", "deployment-balance-monitor", { - // owner: { operator: "eq", value: address }, - // dseq: { operator: "eq", value: deployment.dseq } - // }), - // "_ blank" - // ); - - // handleMenuClose(); - // }; - return ( <> viewDeployment()}> @@ -348,7 +335,6 @@ export const DeploymentListRow: React.FunctionComponent = ({ deployment, {isActive && setIsDepositingDeployment(true)} icon={} text="Add funds" />} changeDeploymentName(deployment.dseq)} icon={} text="Edit name" /> {storageDeploymentData?.manifest && redeploy()} icon={} text="Redeploy" />} - {/* {isActive && onSetAlert()} icon={} text="Balance Alert" />} */} {isActive && onCloseDeployment()} icon={} text="Close" />} diff --git a/deploy-web/src/components/deploymentDetail/DeploymentDetailTopBar.tsx b/deploy-web/src/components/deploymentDetail/DeploymentDetailTopBar.tsx index be9c85088..cdeaa519d 100644 --- a/deploy-web/src/components/deploymentDetail/DeploymentDetailTopBar.tsx +++ b/deploy-web/src/components/deploymentDetail/DeploymentDetailTopBar.tsx @@ -126,19 +126,6 @@ export const DeploymentDetailTopBar: React.FunctionComponent = ({ address } }; - // TODO Alerts - // const onSetAlert = () => { - // window.open( - // UrlService.alertsCreate(null, "akash", "deployment-balance-monitor", { - // owner: { operator: "eq", value: address }, - // dseq: { operator: "eq", value: deployment.dseq } - // }), - // "_blank" - // ); - - // handleMenuClose(); - // }; - return ( <> = ({ address > onChangeName()} icon={} text="Edit Name" /> {storageDeploymentData?.manifest && redeploy()} icon={} text="Redeploy" />} - {/* {isActive && onSetAlert()} icon={} text="Balance Alert" />} */} onCloseDeployment()} icon={} text="Close" /> diff --git a/deploy-web/src/pages/validators/[address].tsx b/deploy-web/src/pages/validators/[address].tsx index adaa93b32..f4d217a74 100644 --- a/deploy-web/src/pages/validators/[address].tsx +++ b/deploy-web/src/pages/validators/[address].tsx @@ -56,7 +56,6 @@ const ValidatorDetailPage: React.FunctionComponent = ({ address, validato - {/** TODO Alerts */} {/* ["SDL_TEMPLATES", id]; static getUserTemplatesKey = (username: string) => ["USER_TEMPLATES", username]; static getUserFavoriteTemplatesKey = (userId: string) => ["USER_FAVORITES_TEMPLATES", userId]; - static getAlertsKey = (userId: string) => ["ALERTS", userId]; - static getAlertEventsKey = (userId: string, alertId: string, skip: number, limit: number) => ["ALERT_EVENTS", userId, alertId, skip, limit]; static getGranterGrants = (address: string) => ["GRANTER_GRANTS", address]; static getGranteeGrants = (address: string) => ["GRANTEE_GRANTS", address]; diff --git a/shared/alertTemplates/akash.ts b/shared/alertTemplates/akash.ts deleted file mode 100644 index 1815f8482..000000000 --- a/shared/alertTemplates/akash.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { NotificationTemplate } from "."; -import { PropertyTypes } from "../propertyTypes"; - -export const akashAlertTemplates: NotificationTemplate[] = [ - { - code: "new-provider", - name: "New Provider", - args: [ - { code: "owner", label: "Owner", type: PropertyTypes.Address }, - { code: "hostUri", label: "Host URI", type: PropertyTypes.String }, - { code: "email", label: "Email", type: PropertyTypes.String }, - { code: "website", label: "Website", type: PropertyTypes.String } - ], - triggers: [ - { - type: "/akash.provider.v1beta2.MsgCreateProvider", - conditions: [ - { key: "owner", arg: "owner" }, - { key: "hostUri", arg: "hostUri" }, - { key: "info.email", arg: "email" }, - { key: "info.website", arg: "website" } - ] - } - ] - }, - { - code: "new-deployment", - name: "New Deployment", - showNoConditionWarning: true, - args: [ - { code: "owner", label: "Owner", type: PropertyTypes.Address }, - { code: "depositor", label: "Depositor", type: PropertyTypes.Address } - ], - triggers: [ - { - type: "/akash.deployment.v1beta2.MsgCreateDeployment", - conditions: [ - { key: "id.owner", arg: "owner" }, - { key: "depositor", arg: "depositor" } - ] - } - ] - }, - { - code: "new-lease", - name: "New Lease", - showNoConditionWarning: true, - args: [ - { code: "owner", label: "Owner", type: PropertyTypes.Address }, - { code: "dseq", label: "DSEQ", type: PropertyTypes.DSEQ }, - { code: "provider", label: "Provider", type: PropertyTypes.Address } - ], - triggers: [ - { - type: "/akash.market.v1beta2.MsgCreateLease", - conditions: [ - { key: "bidId.owner", arg: "owner" }, - { key: "bidId.dseq", arg: "dseq" }, - { key: "bidId.provider", arg: "provider" } - ] - } - ] - }, - { - code: "provider-attribute-signed", - name: "Provider Attribute Signed", - args: [ - { code: "owner", label: "Provider", type: PropertyTypes.Address }, - { code: "auditor", label: "Auditor", type: PropertyTypes.Address } - ], - triggers: [ - { - type: "/akash.audit.v1beta2.MsgSignProviderAttributes", - conditions: [ - { key: "owner", arg: "owner" }, - { key: "auditor", arg: "auditor" } - ] - } - ] - }, - { - code: "deployment-balance-monitor", - name: "Deployment Balance Monitor", - description: "The deployment balance refresh interval is usually 1 hour, but may vary from one provider to another.", - tracker: "DeploymentBalanceMonitor", - args: [ - { code: "owner", label: "Owner", type: PropertyTypes.Address, operators: ["="] }, - { code: "dseq", label: "DSEQ", type: PropertyTypes.DSEQ }, - { code: "threshold", label: "Threshold", type: PropertyTypes.Coin } - ] - } -]; diff --git a/shared/alertTemplates/cosmos.ts b/shared/alertTemplates/cosmos.ts deleted file mode 100644 index 29466cd89..000000000 --- a/shared/alertTemplates/cosmos.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { NotificationTemplate } from "."; -import { PropertyTypes } from "../propertyTypes"; - -export const cosmosAlertTemplates: NotificationTemplate[] = [ - { - code: "new-proposal", - name: "New Proposal", - args: [ - { code: "initialDeposit", label: "Initial Deposit", type: PropertyTypes.Coin }, - { code: "proposer", label: "Proposer", type: PropertyTypes.Address } - ], - triggers: [ - { - type: "/cosmos.gov.v1beta1.MsgSubmitProposal", - conditions: [ - { key: "initialDeposit", arg: "initialDeposit" }, - { key: "proposer", arg: "proposer" } - ] - } - ] - }, - { - code: "new-validator", - name: "New Validator", - args: [ - { code: "minSelfDelegation", label: "Min Self Delegation", type: PropertyTypes.DecimalAsString }, - { code: "commissionRate", label: "Commission Rate", type: PropertyTypes.DecimalAsString }, - { code: "commissionMaxRate", label: "Commission Max Rate", type: PropertyTypes.DecimalAsString }, - { code: "commissionMaxChangeRate", label: "Commission Max Rate Change", type: PropertyTypes.DecimalAsString } - ], - triggers: [ - { - type: "/cosmos.staking.v1beta1.MsgCreateValidator", - conditions: [ - { key: "minSelfDelegation", arg: "minSelfDelegation" }, - { key: "commission.rate", arg: "commissionRate" }, - { key: "commission.maxRate", arg: "commissionMaxRate" }, - { key: "commission.maxRateChange", arg: "commissionMaxRateChange" } - ] - } - ] - }, - { - code: "new-delegation", - name: "Voting Power Added", - description: "This tracks delegations as well as redelegations.", - showNoConditionWarning: true, - args: [ - { code: "delegator", label: "Delegator", type: PropertyTypes.Address }, - { code: "validator", label: "Validator", type: PropertyTypes.ValidatorAddress }, - { code: "amount", label: "Amount", type: PropertyTypes.Coin } - ], - triggers: [ - { - type: "/cosmos.staking.v1beta1.MsgDelegate", - conditions: [ - { key: "delegatorAddress", arg: "delegator" }, - { key: "validatorAddress", arg: "validator" }, - { key: "amount", arg: "amount" } - ] - }, - { - type: "/cosmos.staking.v1beta1.MsgBeginRedelegate", - conditions: [ - { key: "delegatorAddress", arg: "delegator" }, - { key: "validatorDstAddress", arg: "validator" }, - { key: "amount", arg: "amount" } - ] - } - ] - }, - { - code: "voting-power-removed", - name: "Voting Power Removed", - description: "This tracks undelegations as well as redelegations.", - showNoConditionWarning: true, - args: [ - { code: "delegator", label: "Delegator", type: PropertyTypes.Address }, - { code: "validator", label: "Validator", type: PropertyTypes.ValidatorAddress }, - { code: "amount", label: "Amount", type: PropertyTypes.Coin } - ], - triggers: [ - { - type: "/cosmos.staking.v1beta1.MsgUndelegate", - conditions: [ - { key: "delegatorAddress", arg: "delegator" }, - { key: "validatorAddress", arg: "validator" }, - { key: "amount", arg: "amount" } - ] - }, - { - type: "/cosmos.staking.v1beta1.MsgBeginRedelegate", - conditions: [ - { key: "delegatorAddress", arg: "delegator" }, - { key: "validatorSrcAddress", arg: "validator" }, - { key: "amount", arg: "amount" } - ] - } - ] - }, - { - code: "send-tokens", - name: "Send Tokens", - showNoConditionWarning: true, - args: [ - { code: "from", label: "From Address", type: PropertyTypes.Address }, - { code: "to", label: "To Address", type: PropertyTypes.Address }, - { code: "amount", label: "Amount", type: PropertyTypes.Coin } - ], - triggers: [ - { - type: "/cosmos.bank.v1beta1.MsgSend", - conditions: [ - { - key: "fromAddress", - arg: "from" - }, - { - key: "toAddress", - arg: "to" - }, - { - key: "amount", - arg: "amount" - } - ] - } - ] - }, - { - code: "balance-monitor", - name: "Balance Monitor", - description: "This alert will trigger when the balance of the specified address is above or below the specified threshold.", - tracker: "AddressBalanceMonitor", - args: [ - { code: "address", label: "Address", type: PropertyTypes.Address, operators: ["="] }, - { code: "threshold", label: "Threshold", type: PropertyTypes.Coin } - ] - } -]; diff --git a/shared/alertTemplates/index.ts b/shared/alertTemplates/index.ts deleted file mode 100644 index 04ecd1017..000000000 --- a/shared/alertTemplates/index.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { PropertyTypes } from "../propertyTypes"; - -interface ConditionTemplate { - key: string; - arg?: string; - value?: string; -} - -interface TriggerTemplate { - type: string; - conditions?: ConditionTemplate[]; -} - -export interface NotificationTemplateArg { - code: string; - label: string; - type: PropertyTypes; - required?: boolean; - operators?: string[]; -} - -export interface NotificationTemplate { - code: string; - name: string; - description?: string; - args?: NotificationTemplateArg[]; - triggers?: TriggerTemplate[]; - tracker?: MonitoredValueTrackerType; - showNoConditionWarning?: boolean; -} - -import { cosmosAlertTemplates } from "./cosmos"; -import { akashAlertTemplates } from "./akash"; -import { stargazeAlertTemplates } from "./stargaze"; - -export const alertTemplatesByChain = { - akash: akashAlertTemplates, - stargaze: stargazeAlertTemplates -}; - -export const allAlertTemplates = [...cosmosAlertTemplates, ...akashAlertTemplates, ...stargazeAlertTemplates]; -export type MonitoredValueTrackerType = "AddressBalanceMonitor" | "DeploymentBalanceMonitor"; diff --git a/shared/alertTemplates/stargaze.ts b/shared/alertTemplates/stargaze.ts deleted file mode 100644 index e65d100c7..000000000 --- a/shared/alertTemplates/stargaze.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { NotificationTemplate } from "."; -import { CustomContractTypePropertyKey } from "../msgSchemas/cosmosSchemas"; -import { PropertyTypes } from "../propertyTypes"; - -const NFTMarketplaceContractAddress = "stars1fvhcnyddukcqfnt7nlwv3thm5we22lyxyxylr9h77cvgkcn43xfsvgv0pl"; - -export const stargazeAlertTemplates: NotificationTemplate[] = [ - { - //https://www.mintscan.io/stargaze/txs/FF294515CDAAB58E4D4AF37C7EE8118C11D64289555129ED19BBE2863983C0E0 - code: "stargaze-new-offer", - name: "New Offer", - args: [ - { code: "collection", label: "Collection", type: PropertyTypes.ContractAddress, required: true }, - { code: "tokenId", label: "Token ID", type: PropertyTypes.Integer, operators: ["="], required: true }, - { code: "price", label: "Price", type: PropertyTypes.Coin } - ], - triggers: [ - { - type: "/cosmwasm.wasm.v1.MsgExecuteContract", - conditions: [ - { key: "contract", value: NFTMarketplaceContractAddress }, - { key: CustomContractTypePropertyKey, value: "set_bid" }, - { key: "msg.collection", arg: "collection" }, - { key: "msg.token_id", arg: "tokenId" }, - { key: "funds", arg: "price" } - ] - } - ] - }, - { - //https://www.mintscan.io/stargaze/txs/B5651967FF6B9E95D2C88D2890134254DE3FB226166897B7007AC9810826EBB9 - code: "stargaze-listed-for-sale", - name: "Listed for sale", - args: [ - { code: "collection", label: "Collection", type: PropertyTypes.ContractAddress, required: true }, - { code: "tokenId", label: "Token ID", type: PropertyTypes.Integer, operators: ["="], required: true }, - { code: "price", label: "Price", type: PropertyTypes.Coin } - ], - triggers: [ - { - type: "/cosmwasm.wasm.v1.MsgExecuteContract", - conditions: [ - { key: "contract", value: NFTMarketplaceContractAddress }, - { key: CustomContractTypePropertyKey, value: "set_ask" }, - { key: "msg.collection", arg: "collection" }, - { key: "msg.token_id", arg: "tokenId" }, - { key: "msg.price", arg: "price" } - ] - } - ] - }, - { - //https://www.mintscan.io/stargaze/txs/B4E6FCFC2082925758300ACF0A64A6B8D7959E9A58ADE76B47E5D79B36E81D17 - code: "stargaze-ask-price-updated", - name: "Price changed", - args: [ - { code: "collection", label: "Collection", type: PropertyTypes.ContractAddress, required: true }, - { code: "tokenId", label: "Token ID", type: PropertyTypes.Integer, operators: ["="], required: true }, - { code: "price", label: "Price", type: PropertyTypes.Coin } - ], - triggers: [ - { - type: "/cosmwasm.wasm.v1.MsgExecuteContract", - conditions: [ - { key: "contract", value: NFTMarketplaceContractAddress }, - { key: CustomContractTypePropertyKey, value: "update_ask_price" }, - { key: "msg.collection", arg: "collection" }, - { key: "msg.token_id", arg: "tokenId" }, - { key: "msg.price", arg: "price" } - ] - } - ] - } -]; diff --git a/shared/index.ts b/shared/index.ts deleted file mode 100644 index e99e0fbc8..000000000 --- a/shared/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./msgSchemas"; -export * from "./propertyTypes"; -export * from "./alertTemplates" \ No newline at end of file diff --git a/shared/msgSchemas/akashSchemas.ts b/shared/msgSchemas/akashSchemas.ts deleted file mode 100644 index 52d3f4f0c..000000000 --- a/shared/msgSchemas/akashSchemas.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { IMessageSchema } from "."; -import { PropertyTypes } from "../propertyTypes"; - -const schemaDeploymentID = { - owner: PropertyTypes.Address, - dseq: PropertyTypes.DSEQ -}; - -const schemaBidID = { - owner: PropertyTypes.Address, - provider: PropertyTypes.Address, - dseq: PropertyTypes.DSEQ, - gseq: PropertyTypes.Integer, - oseq: PropertyTypes.Integer -}; - -export const schemaAttributeList = [ - { - key: PropertyTypes.String, - value: PropertyTypes.String - } -]; - -export const akashSchemas: IMessageSchema[] = [ - { - type: "/akash.audit.v1beta2.MsgSignProviderAttributes", - properties: { - owner: PropertyTypes.Address, - auditor: PropertyTypes.Address, - attributes: schemaAttributeList - } - }, - { - type: "/akash.provider.v1beta2.MsgCreateProvider", - properties: { - owner: PropertyTypes.Address, - hostUri: PropertyTypes.String, - attributes: schemaAttributeList, - info: { - email: PropertyTypes.String, - website: PropertyTypes.String - } - } - }, - { - type: "/akash.deployment.v1beta2.MsgCreateDeployment", - showNoConditionWarning: true, - properties: { - id: schemaDeploymentID, - groups: [ - { - name: PropertyTypes.String, - requirements: { - signedBy: { - allOf: PropertyTypes.AddressList, - anyOf: PropertyTypes.AddressList - }, - attributes: schemaAttributeList - }, - resources: [ - { - resources: { - cpu: { units: { val: PropertyTypes.CPU }, attributes: schemaAttributeList }, - memory: { quantity: { val: PropertyTypes.Memory }, attributes: schemaAttributeList }, - storage: [{ name: PropertyTypes.String, quantity: { val: PropertyTypes.Storage }, attributes: schemaAttributeList }], - endpoints: [{ kind: PropertyTypes.EndpointKind, sequenceNumber: PropertyTypes.Integer }] - }, - count: PropertyTypes.Integer, - price: PropertyTypes.Coin // TODO: Test DecCoin - } - ] - } - ], - //version: - deposit: PropertyTypes.Coin, - depositor: PropertyTypes.Address - } - }, - { - type: "/akash.market.v1beta2.MsgCreateLease", - showNoConditionWarning: true, - properties: { - bidId: schemaBidID - } - }, - { - type: "/akash.market.v1beta2.MsgWithdrawLease", - showNoConditionWarning: true, - properties: { - bidId: schemaBidID - } - } -]; diff --git a/shared/msgSchemas/cosmosSchemas.ts b/shared/msgSchemas/cosmosSchemas.ts deleted file mode 100644 index 199d97507..000000000 --- a/shared/msgSchemas/cosmosSchemas.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { IMessageSchema } from "."; -import { PropertyTypes } from "../propertyTypes"; -export const CustomContractTypePropertyKey = "__CONTRACT_TYPE__"; - -export const cosmosSchemas: IMessageSchema[] = [ - { - type: "/cosmos.bank.v1beta1.MsgSend", - showNoConditionWarning: true, - properties: { - fromAddress: PropertyTypes.Address, - toAddress: PropertyTypes.Address, - amount: PropertyTypes.Coin - } - }, - { - type: "/cosmos.bank.v1beta1.MsgMultiSend", - showNoConditionWarning: true, - properties: { - inputs: [ - { - address: PropertyTypes.Address, - coins: PropertyTypes.Coin - } - ], - outputs: [ - { - address: PropertyTypes.Address, - coins: PropertyTypes.Coin - } - ] - } - }, - { - type: "/cosmos.gov.v1beta1.MsgSubmitProposal", - properties: { - initialDeposit: PropertyTypes.Coin, - proposer: PropertyTypes.Address - } - }, - { - type: "/cosmos.staking.v1beta1.MsgCreateValidator", - properties: { - minSelfDelegation: PropertyTypes.DecimalAsString, - delegatorAddress: PropertyTypes.Address, - validatorAddress: PropertyTypes.ValidatorAddress, - value: PropertyTypes.Coin, - description: { - details: PropertyTypes.String, - moniker: PropertyTypes.String, - website: PropertyTypes.String, - identity: PropertyTypes.String, - securityContact: PropertyTypes.String - }, - commission: { - rate: PropertyTypes.DecimalAsString, - maxRate: PropertyTypes.DecimalAsString, - maxChangeRate: PropertyTypes.DecimalAsString - } - //pubkey - } - }, - { - type: "/cosmos.staking.v1beta1.MsgDelegate", - showNoConditionWarning: true, - properties: { - delegatorAddress: PropertyTypes.Address, - validatorAddress: PropertyTypes.ValidatorAddress, - amount: PropertyTypes.Coin - } - }, - { - type: "/cosmos.staking.v1beta1.MsgBeginRedelegate", - showNoConditionWarning: true, - properties: { - delegatorAddress: PropertyTypes.Address, - validatorSrcAddress: PropertyTypes.ValidatorAddress, - validatorDstAddress: PropertyTypes.ValidatorAddress, - amount: PropertyTypes.Coin - } - }, - { - type: "/cosmos.staking.v1beta1.MsgUndelegate", - showNoConditionWarning: true, - properties: { - delegatorAddress: PropertyTypes.Address, - validatorAddress: PropertyTypes.ValidatorAddress, - amount: PropertyTypes.Coin - } - } -]; diff --git a/shared/msgSchemas/index.ts b/shared/msgSchemas/index.ts deleted file mode 100644 index 424254c9c..000000000 --- a/shared/msgSchemas/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { PropertyTypes } from "../propertyTypes"; -import { akashSchemas } from "./akashSchemas"; -import { cosmosSchemas } from "./cosmosSchemas"; -import { stargazeSchemas } from "./stargazeSchemas"; - -export type MessageSchemaProperty = PropertyTypes | { [key: string]: MessageSchemaProperty } | { [key: string]: MessageSchemaProperty }[]; -export interface IMessageSchema { - type: string; - disableCustomAlerts?: boolean; - showNoConditionWarning?: boolean; - properties: { [key: string]: MessageSchemaProperty }; -} - -export const msgSchemas: IMessageSchema[] = [...cosmosSchemas, ...akashSchemas, ...stargazeSchemas]; diff --git a/shared/msgSchemas/stargazeSchemas.ts b/shared/msgSchemas/stargazeSchemas.ts deleted file mode 100644 index de09d05ce..000000000 --- a/shared/msgSchemas/stargazeSchemas.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { IMessageSchema } from "."; -import { PropertyTypes } from "../propertyTypes"; -export const CustomContractTypePropertyKey = "__CONTRACT_TYPE__"; - -export const stargazeSchemas: IMessageSchema[] = [ - { - type: "/cosmwasm.wasm.v1.MsgExecuteContract", - disableCustomAlerts: true, - showNoConditionWarning: true, - properties: { - sender: PropertyTypes.Address, - contract: PropertyTypes.String, - [CustomContractTypePropertyKey]: PropertyTypes.String, - msg: { - set_bid: { - collection: PropertyTypes.ContractAddress, - expires: PropertyTypes.TimestampNano, - token_id: PropertyTypes.IntegerAsString, - sale_type: PropertyTypes.String - }, - set_ask: { - collection: PropertyTypes.ContractAddress, - expires: PropertyTypes.TimestampNano, - sale_type: PropertyTypes.String, - reserve_for: PropertyTypes.Address, - funds_recipient: PropertyTypes.Address, - price: PropertyTypes.Coin, - token_id: PropertyTypes.IntegerAsString - }, - update_ask_price: { - collection: PropertyTypes.ContractAddress, - price: PropertyTypes.Coin, - token_id: PropertyTypes.IntegerAsString - } - }, - funds: PropertyTypes.Coin - } - } -]; diff --git a/shared/propertyTypes.ts b/shared/propertyTypes.ts deleted file mode 100644 index dad45cf33..000000000 --- a/shared/propertyTypes.ts +++ /dev/null @@ -1,19 +0,0 @@ -export enum PropertyTypes { - String = "String", - Integer = "Integer", - DecimalAsString = "DecimalAsString", - IntegerAsString = "IntegerAsString", - Address = "Address", - AddressList = "AddressList", - ContractAddress = "ContractAddress", - ValidatorAddress = "ValidatorAddress", - TimestampNano = "TimestampNano", - Coin = "Coin", - - // Akash - DSEQ = "DSEQ", - CPU = "CPU", - Memory = "Memory", - Storage = "Storage", - EndpointKind = "EndpointKind" -} From 420014306d94696bb10bc4f6e53d74f657cf4a7d Mon Sep 17 00:00:00 2001 From: Redm4x Date: Thu, 17 Aug 2023 01:06:24 -0400 Subject: [PATCH 3/7] Improve typings --- deploy-web/package-lock.json | 13 +++ deploy-web/package.json | 1 + .../deployment/DeploymentListRow.tsx | 7 +- .../deploymentDetail/DeploymentLeaseShell.tsx | 9 +- .../deploymentDetail/ManifestUpdate.tsx | 3 +- .../src/components/providers/LeaseRow.tsx | 2 +- .../src/components/shared/CodeSnippet.tsx | 4 +- .../CertificateProviderContext.tsx | 9 +- .../LocalNoteProvider/LocalNoteContext.tsx | 20 ++--- .../SettingsProviderContext.tsx | 1 - deploy-web/src/enums/index.ts | 1 - deploy-web/src/hooks/useLocalStorage.ts | 18 ++-- deploy-web/src/hooks/useThrottle.ts | 2 +- .../src/pages/addresses/[address]/index.tsx | 3 - deploy-web/src/pages/deployments/index.tsx | 16 ---- .../src/pages/user/settings/address-book.tsx | 2 - deploy-web/src/pages/validators/[address].tsx | 2 - deploy-web/src/queries/queryKeys.ts | 18 ++-- deploy-web/src/queries/useBalancesQuery.ts | 17 ++-- deploy-web/src/queries/useDeploymentQuery.ts | 8 +- deploy-web/src/queries/useLeaseQuery.ts | 16 ++-- deploy-web/src/types/balances.ts | 88 +++++++++++++++++++ deploy-web/src/types/certificate.ts | 14 +++ .../src/utils/TransactionMessageData.ts | 11 +-- deploy-web/src/utils/analytics.ts | 3 - deploy-web/src/utils/apiUtils.ts | 28 +++--- deploy-web/src/utils/certificateUtils.ts | 2 +- .../src/utils/deploymentData/helpers.ts | 6 +- deploy-web/src/utils/deploymentData/index.ts | 2 +- .../src/utils/deploymentData/v1beta2.ts | 2 +- .../src/utils/deploymentData/v1beta3.ts | 2 +- deploy-web/src/utils/deploymentDetailUtils.ts | 6 +- .../src/utils/deploymentLocalDataUtils.ts | 17 ++-- deploy-web/src/utils/deploymentUtils.ts | 3 +- deploy-web/src/utils/priceUtils.ts | 9 +- deploy-web/src/utils/providerUtils.ts | 50 ++--------- deploy-web/src/utils/stringUtils.ts | 13 ++- deploy-web/src/utils/urlUtils.ts | 4 +- deploy-web/src/utils/walletUtils.ts | 20 +++-- 39 files changed, 264 insertions(+), 188 deletions(-) delete mode 100644 deploy-web/src/enums/index.ts create mode 100644 deploy-web/src/types/balances.ts create mode 100644 deploy-web/src/types/certificate.ts diff --git a/deploy-web/package-lock.json b/deploy-web/package-lock.json index 39cd4636b..2fa14ffac 100644 --- a/deploy-web/package-lock.json +++ b/deploy-web/package-lock.json @@ -80,6 +80,7 @@ "@types/file-saver": "^2.0.5", "@types/js-yaml": "^4.0.5", "@types/json2csv": "^5.0.3", + "@types/lodash": "^4.14.197", "@types/node": "^12.12.21", "@types/nprogress": "^0.2.0", "@types/react": "^17.0.2", @@ -5487,6 +5488,12 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/lodash": { + "version": "4.14.197", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.197.tgz", + "integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==", + "dev": true + }, "node_modules/@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", @@ -19761,6 +19768,12 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "@types/lodash": { + "version": "4.14.197", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.197.tgz", + "integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==", + "dev": true + }, "@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", diff --git a/deploy-web/package.json b/deploy-web/package.json index f4e6fdbb1..0951647e4 100644 --- a/deploy-web/package.json +++ b/deploy-web/package.json @@ -84,6 +84,7 @@ "@types/file-saver": "^2.0.5", "@types/js-yaml": "^4.0.5", "@types/json2csv": "^5.0.3", + "@types/lodash": "^4.14.197", "@types/node": "^12.12.21", "@types/nprogress": "^0.2.0", "@types/react": "^17.0.2", diff --git a/deploy-web/src/components/deployment/DeploymentListRow.tsx b/deploy-web/src/components/deployment/DeploymentListRow.tsx index 232700385..9a0c4ed18 100644 --- a/deploy-web/src/components/deployment/DeploymentListRow.tsx +++ b/deploy-web/src/components/deployment/DeploymentListRow.tsx @@ -15,7 +15,7 @@ import { useAllLeases } from "@src/queries/useLeaseQuery"; import { makeStyles } from "tss-react/mui"; import { useRouter } from "next/router"; import { getAvgCostPerMonth, getTimeLeft, useRealTimeLeft } from "@src/utils/priceUtils"; -import { Box, Checkbox, CircularProgress, darken, IconButton, Menu, TableCell, Tooltip, Typography, useMediaQuery, useTheme } from "@mui/material"; +import { Box, Checkbox, CircularProgress, darken, IconButton, Menu, TableCell, Tooltip, Typography } from "@mui/material"; import { UrlService } from "@src/utils/urlUtils"; import { cx } from "@emotion/css"; import { CustomMenuItem } from "../shared/CustomMenuItem"; @@ -112,7 +112,7 @@ export const DeploymentListRow: React.FunctionComponent = ({ deployment, const hasActiveLeases = hasLeases && filteredLeases.some(l => l.state === "active"); const deploymentCost = hasLeases ? filteredLeases.reduce((prev, current) => prev + parseFloat(current.price.amount), 0) : 0; const timeLeft = getTimeLeft(deploymentCost, deployment.escrowBalance); - const realTimeLeft = useRealTimeLeft(deploymentCost, deployment.escrowBalance, deployment.escrowAccount.settled_at, deployment.createdAt); + const realTimeLeft = useRealTimeLeft(deploymentCost, deployment.escrowBalance, parseFloat(deployment.escrowAccount.settled_at), deployment.createdAt); const deploymentName = deployment.name ? ( <> @@ -125,9 +125,8 @@ export const DeploymentListRow: React.FunctionComponent = ({ deployment, ); const showWarning = differenceInCalendarDays(timeLeft, new Date()) < 7; const escrowBalance = isActive && hasActiveLeases ? realTimeLeft?.escrow : deployment.escrowBalance; - const amountSpent = isActive && hasActiveLeases ? realTimeLeft?.amountSpent : deployment.transferred.amount; + const amountSpent = isActive && hasActiveLeases ? realTimeLeft?.amountSpent : parseFloat(deployment.transferred.amount); const isValidTimeLeft = isActive && hasActiveLeases && isValid(realTimeLeft?.timeLeft); - const theme = useTheme(); const avgCost = udenomToDenom(getAvgCostPerMonth(deploymentCost)); const storageDeploymentData = getDeploymentData(deployment?.dseq); const denomData = useDenomData(deployment.escrowAccount.balance.denom); diff --git a/deploy-web/src/components/deploymentDetail/DeploymentLeaseShell.tsx b/deploy-web/src/components/deploymentDetail/DeploymentLeaseShell.tsx index 166a87cab..bddfa3288 100644 --- a/deploy-web/src/components/deploymentDetail/DeploymentLeaseShell.tsx +++ b/deploy-web/src/components/deploymentDetail/DeploymentLeaseShell.tsx @@ -1,22 +1,21 @@ import React, { useCallback, useEffect, useRef, useState } from "react"; import { useCertificate } from "../../context/CertificateProvider"; -// import { ShellDownloadModal } from "./ShellDownloadModal"; import { LeaseSelect } from "./LeaseSelect"; import { useLeaseStatus } from "@src/queries/useLeaseQuery"; import { Alert, Box, Button, CircularProgress } from "@mui/material"; import ViewPanel from "../shared/ViewPanel"; import { ServiceSelect } from "./ServiceSelect"; import { ShellDownloadModal } from "./ShellDownloadModal"; -import useWebSocket from "react-use-websocket"; import { PROVIDER_PROXY_URL_WS } from "@src/utils/constants"; import { XTermRefType } from "@src/lib/XTerm/XTerm"; import { XTerm } from "@src/lib/XTerm"; import { LeaseShellCode } from "@src/types/shell"; import { useAkashProviders } from "@src/context/AkashProvider"; import { useCustomWebSocket } from "@src/hooks/useCustomWebSocket"; +import { LeaseDto } from "@src/types/deployment"; type Props = { - leases: Array; // Type + leases: LeaseDto[]; }; export const DeploymentLeaseShell: React.FunctionComponent = ({ leases }) => { @@ -26,7 +25,7 @@ export const DeploymentLeaseShell: React.FunctionComponent = ({ leases }) const [isConnectionClosed, setIsConnectionClosed] = useState(false); const [services, setServices] = useState([]); const [selectedService, setSelectedService] = useState(null); - const [selectedLease, setSelectedLease] = useState(null); + const [selectedLease, setSelectedLease] = useState(null); const [isShowingDownloadModal, setIsShowingDownloadModal] = useState(false); const [isChangingSocket, setIsChangingSocket] = useState(false); const { providers } = useAkashProviders(); @@ -36,7 +35,7 @@ export const DeploymentLeaseShell: React.FunctionComponent = ({ leases }) data: leaseStatus, refetch: getLeaseStatus, isFetching: isLoadingStatus - } = useLeaseStatus(providerInfo?.host_uri, selectedLease || {}, { + } = useLeaseStatus(providerInfo?.host_uri, selectedLease, { enabled: false }); const currentUrl = useRef(null); diff --git a/deploy-web/src/components/deploymentDetail/ManifestUpdate.tsx b/deploy-web/src/components/deploymentDetail/ManifestUpdate.tsx index b1f2a50c7..f1ef9347c 100644 --- a/deploy-web/src/components/deploymentDetail/ManifestUpdate.tsx +++ b/deploy-web/src/components/deploymentDetail/ManifestUpdate.tsx @@ -21,8 +21,7 @@ import { event } from "nextjs-google-analytics"; import { AnalyticsEvents } from "@src/utils/analytics"; import { useAkashProviders } from "@src/context/AkashProvider"; import { CustomTooltip } from "../shared/CustomTooltip"; - -const yaml = require("js-yaml"); +import yaml from "js-yaml"; export const useStyles = makeStyles()(theme => ({ title: { diff --git a/deploy-web/src/components/providers/LeaseRow.tsx b/deploy-web/src/components/providers/LeaseRow.tsx index 82cfefa90..ed6d40b20 100644 --- a/deploy-web/src/components/providers/LeaseRow.tsx +++ b/deploy-web/src/components/providers/LeaseRow.tsx @@ -46,7 +46,7 @@ const MemoLeaseRow: React.FunctionComponent = ({ lease }) => {
- +
diff --git a/deploy-web/src/components/shared/CodeSnippet.tsx b/deploy-web/src/components/shared/CodeSnippet.tsx index 962f4b09f..b138ea35d 100644 --- a/deploy-web/src/components/shared/CodeSnippet.tsx +++ b/deploy-web/src/components/shared/CodeSnippet.tsx @@ -1,4 +1,4 @@ -import { lighten, Box, IconButton, darken } from "@mui/material"; +import { lighten, Box, IconButton } from "@mui/material"; import FileCopyIcon from "@mui/icons-material/FileCopy"; import { useSnackbar } from "notistack"; import { useRef } from "react"; @@ -30,7 +30,7 @@ const useStyles = makeStyles()(theme => ({ export const CodeSnippet = ({ code }) => { const { classes } = useStyles(); const { enqueueSnackbar } = useSnackbar(); - const codeRef = useRef(); + const codeRef = useRef(); const onCopyClick = () => { copyTextToClipboard(code); diff --git a/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx b/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx index e32483645..16e49dba6 100644 --- a/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx +++ b/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx @@ -10,8 +10,9 @@ import { useKeplr } from "../KeplrWalletProvider"; import { TransactionMessageData } from "@src/utils/TransactionMessageData"; import { event } from "nextjs-google-analytics"; import { AnalyticsEvents } from "@src/utils/analytics"; +import { RestApiCertificatesResponseType } from "@src/types/certificate"; -type LocalCert = { +export type LocalCert = { certPem: string; keyPem: string; address: string; @@ -76,7 +77,9 @@ export const CertificateProvider = ({ children }) => { setIsLoadingCertificates(true); try { - const response = await axios.get(`${apiEndpoint}/akash/cert/${networkVersion}/certificates/list?filter.state=valid&filter.owner=${address}`); + const response = await axios.get( + `${apiEndpoint}/akash/cert/${networkVersion}/certificates/list?filter.state=valid&filter.owner=${address}` + ); const certs = (response.data.certificates || []).map(cert => { const parsed = atob(cert.certificate.cert); const pem = getCertPem(parsed); @@ -156,7 +159,7 @@ export const CertificateProvider = ({ children }) => { certs.push(_cert); - if (_wallet.address === currentWallet.address) { + if (_wallet.address === currentWallet?.address) { setLocalCert(_cert); } } diff --git a/deploy-web/src/context/LocalNoteProvider/LocalNoteContext.tsx b/deploy-web/src/context/LocalNoteProvider/LocalNoteContext.tsx index eee7a1ddd..da89db956 100644 --- a/deploy-web/src/context/LocalNoteProvider/LocalNoteContext.tsx +++ b/deploy-web/src/context/LocalNoteProvider/LocalNoteContext.tsx @@ -1,4 +1,4 @@ -import { getDeploymentLocalData } from "@src/utils/deploymentLocalDataUtils"; +import { LocalDeploymentData, getDeploymentLocalData } from "@src/utils/deploymentLocalDataUtils"; import { getProviderLocalData, updateProviderLocalData } from "@src/utils/providerUtils"; import React, { useState, useEffect } from "react"; import { DeploymentNameModal } from "./DeploymentNameModal"; @@ -6,16 +6,16 @@ import { DeploymentNameModal } from "./DeploymentNameModal"; type ContextType = { getDeploymentName: (dseq: string | number) => string; changeDeploymentName: (dseq: string | number) => void; - getDeploymentData: (dseq: string | number) => any; // TODO Type - favoriteProviders: any; // TODO: type - updateFavoriteProviders: (newFavorites: any) => void; // TODO + getDeploymentData: (dseq: string | number) => LocalDeploymentData; + favoriteProviders: string[]; + updateFavoriteProviders: (newFavorites: string[]) => void; }; const LocalNoteProviderContext = React.createContext>({}); export const LocalNoteProvider = ({ children }) => { - const [dseq, setDseq] = useState(null); - const [favoriteProviders, setFavoriteProviders] = useState([]); + const [dseq, setDseq] = useState(null); + const [favoriteProviders, setFavoriteProviders] = useState([]); useEffect(() => { const localProviderData = getProviderLocalData(); @@ -24,7 +24,7 @@ export const LocalNoteProvider = ({ children }) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const updateFavoriteProviders = newFavorites => { + const updateFavoriteProviders = (newFavorites: string[]) => { updateProviderLocalData({ favorites: newFavorites }); setFavoriteProviders(newFavorites); }; @@ -42,11 +42,7 @@ export const LocalNoteProvider = ({ children }) => { const getDeploymentData = (dseq: string | number) => { const localData = getDeploymentLocalData(dseq); - if (localData) { - return localData; - } - - return null; + return localData ?? null; }; const changeDeploymentName = (dseq: string | number) => { diff --git a/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx b/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx index 7917efd18..0e22e3307 100644 --- a/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx +++ b/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx @@ -6,7 +6,6 @@ import { mainnetId, mainnetNodes } from "@src/utils/constants"; import { useLocalStorage } from "@src/hooks/useLocalStorage"; import { migrateLocalStorage } from "@src/utils/localStorage"; import { initAppTypes } from "@src/utils/init"; -import { Box, CircularProgress, Typography } from "@mui/material"; type Node = { api: string; diff --git a/deploy-web/src/enums/index.ts b/deploy-web/src/enums/index.ts deleted file mode 100644 index 07d729d19..000000000 --- a/deploy-web/src/enums/index.ts +++ /dev/null @@ -1 +0,0 @@ -export enum Enum {} diff --git a/deploy-web/src/hooks/useLocalStorage.ts b/deploy-web/src/hooks/useLocalStorage.ts index ed1a4c10a..7b6578ce1 100644 --- a/deploy-web/src/hooks/useLocalStorage.ts +++ b/deploy-web/src/hooks/useLocalStorage.ts @@ -1,23 +1,23 @@ import { useKeplr } from "@src/context/KeplrWalletProvider"; import { useEffect, useState } from "react"; -import { useEventListener, useLocalStorage as useLs } from "usehooks-ts"; +import { useEventListener } from "usehooks-ts"; export const useLocalStorage = () => { const { address } = useKeplr(); - const getLocalStorageItem = key => { + const getLocalStorageItem = (key: string) => { const selectedNetworkId = localStorage.getItem("selectedNetworkId"); return localStorage.getItem(`${selectedNetworkId}${address ? "/" + address : ""}/${key}`); }; - const setLocalStorageItem = (key, value) => { + const setLocalStorageItem = (key: string, value: string) => { const selectedNetworkId = localStorage.getItem("selectedNetworkId"); localStorage.setItem(`${selectedNetworkId}${address ? "/" + address : ""}/${key}`, value); }; - const removeLocalStorageItem = key => { + const removeLocalStorageItem = (key: string) => { const selectedNetworkId = localStorage.getItem("selectedNetworkId"); localStorage.removeItem(`${selectedNetworkId}${address ? "/" + address : ""}/${key}`); }; @@ -29,7 +29,7 @@ export const useLocalStorage = () => { }; }; -export function useCustomLocalStorage(key, initialValue) { +export function useCustomLocalStorage(key: string, initialValue: T) { // Get from local storage then // parse stored json or return initialValue const readValue = () => { @@ -40,7 +40,7 @@ export function useCustomLocalStorage(key, initialValue) { try { const item = window.localStorage.getItem(key); - return item ? parseJSON(item) : initialValue; + return item ? (parseJSON(item) as T) : initialValue; } catch (error) { console.warn(`Error reading localStorage key “${key}”:`, error); return initialValue; @@ -49,11 +49,11 @@ export function useCustomLocalStorage(key, initialValue) { // State to store our value // Pass initial state function to useState so logic is only executed once - const [storedValue, setStoredValue] = useState(readValue); + const [storedValue, setStoredValue] = useState(readValue); // Return a wrapped version of useState's setter function that ... // ... persists the new value to localStorage. - const setValue = value => { + const setValue = (value: T | ((newValue: T) => T)) => { // Prevent build error "window is undefined" but keeps working if (typeof window == "undefined") { console.warn(`Tried setting localStorage key “${key}” even though environment is not a client`); @@ -96,7 +96,7 @@ export function useCustomLocalStorage(key, initialValue) { } // A wrapper for "JSON.parse()"" to support "undefined" value -function parseJSON(value) { +function parseJSON(value: string) { try { return value === "undefined" ? undefined : JSON.parse(value ?? ""); } catch (error) { diff --git a/deploy-web/src/hooks/useThrottle.ts b/deploy-web/src/hooks/useThrottle.ts index 335cb4f55..b6935d6d6 100644 --- a/deploy-web/src/hooks/useThrottle.ts +++ b/deploy-web/src/hooks/useThrottle.ts @@ -1,7 +1,7 @@ import { useCallback } from "react"; import throttle from "lodash/throttle"; -export const useThrottledCallback = (effect, deps, delay) => { +export const useThrottledCallback = (effect: () => void, deps: any[], delay: number) => { // eslint-disable-next-line react-hooks/exhaustive-deps return useCallback( throttle(() => { diff --git a/deploy-web/src/pages/addresses/[address]/index.tsx b/deploy-web/src/pages/addresses/[address]/index.tsx index 0b1e24556..03758a5ad 100644 --- a/deploy-web/src/pages/addresses/[address]/index.tsx +++ b/deploy-web/src/pages/addresses/[address]/index.tsx @@ -148,9 +148,6 @@ const AddressDetailPage: React.FunctionComponent = ({ address, addressDet {address in addressNames ? : } - - {/** TODO Alerts */} - {/* */} } labelWidth="10rem" diff --git a/deploy-web/src/pages/deployments/index.tsx b/deploy-web/src/pages/deployments/index.tsx index 50238f660..a07a918ac 100644 --- a/deploy-web/src/pages/deployments/index.tsx +++ b/deploy-web/src/pages/deployments/index.tsx @@ -269,22 +269,6 @@ const DeploymentsPage: React.FunctionComponent = ({}) => { You have {orderedDeployments.length} {isFilteringActive ? " active" : ""} deployments
- - {/** TODO Alerts */} - {/* - Monitor your deployment balances with - - - - Cloudmos Alerts - - - - */} )} diff --git a/deploy-web/src/pages/user/settings/address-book.tsx b/deploy-web/src/pages/user/settings/address-book.tsx index 838cdd1c6..faadee708 100644 --- a/deploy-web/src/pages/user/settings/address-book.tsx +++ b/deploy-web/src/pages/user/settings/address-book.tsx @@ -56,8 +56,6 @@ const UserAddressBookPage: React.FunctionComponent = ({}) => { {name} - {/** TODO Alerts */} - {/* */} { diff --git a/deploy-web/src/pages/validators/[address].tsx b/deploy-web/src/pages/validators/[address].tsx index f4d217a74..19234bf28 100644 --- a/deploy-web/src/pages/validators/[address].tsx +++ b/deploy-web/src/pages/validators/[address].tsx @@ -63,8 +63,6 @@ const ValidatorDetailPage: React.FunctionComponent = ({ address, validato {validator.address} - - } /> */} diff --git a/deploy-web/src/queries/queryKeys.ts b/deploy-web/src/queries/queryKeys.ts index 2b81fc1e4..b3b70a2f4 100644 --- a/deploy-web/src/queries/queryKeys.ts +++ b/deploy-web/src/queries/queryKeys.ts @@ -24,20 +24,20 @@ export class QueryKeys { static getGranteeGrants = (address: string) => ["GRANTEE_GRANTS", address]; // Deploy - static getDeploymentListKey = address => ["DEPLOYMENT_LIST", address]; - static getDeploymentDetailKey = (address, dseq) => ["DEPLOYMENT_DETAIL", address, dseq]; - static getAllLeasesKey = address => ["ALL_LEASES", address]; - static getLeasesKey = (address, dseq) => ["LEASE_LIST", address, dseq]; - static getLeaseStatusKey = (dseq, gseq, oseq) => ["LEASE_STATUS", dseq, gseq, oseq]; - static getBidListKey = (address, dseq) => ["BID_LIST", address, dseq]; + static getDeploymentListKey = (address: string) => ["DEPLOYMENT_LIST", address]; + static getDeploymentDetailKey = (address: string, dseq: string) => ["DEPLOYMENT_DETAIL", address, dseq]; + static getAllLeasesKey = (address: string) => ["ALL_LEASES", address]; + static getLeasesKey = (address: string, dseq: string) => ["LEASE_LIST", address, dseq]; + static getLeaseStatusKey = (dseq: string, gseq: number, oseq: number) => ["LEASE_STATUS", dseq, gseq, oseq]; + static getBidListKey = (address: string, dseq: string) => ["BID_LIST", address, dseq]; static getProvidersKey = () => ["PROVIDERS"]; - static getProviderDetailKey = owner => ["PROVIDERS", owner]; + static getProviderDetailKey = (owner: string) => ["PROVIDERS", owner]; static getDataNodeProvidersKey = () => ["DATA_NODE_PROVIDERS"]; - static getProviderStatusKey = providerUri => ["PROVIDER_STATUS", providerUri]; + static getProviderStatusKey = (providerUri: string) => ["PROVIDER_STATUS", providerUri]; static getNetworkCapacity = () => ["NETWORK_CAPACITY"]; static getProviderActiveLeasesGraph = (providerAddress: string) => ["PROVIDER_ACTIVE_LEASES_GRAPH", providerAddress]; static getAuditorsKey = () => ["AUDITORS"]; - static getBlockKey = id => ["BLOCK", id]; + static getBlockKey = (id: string) => ["BLOCK", id]; static getBalancesKey = (address: string) => ["BALANCES", address]; static getTemplatesKey = () => ["TEMPLATES"]; static getProviderAttributesSchema = () => ["PROVIDER_ATTRIBUTES_SCHEMA"]; diff --git a/deploy-web/src/queries/useBalancesQuery.ts b/deploy-web/src/queries/useBalancesQuery.ts index 2812a007e..9097029c1 100644 --- a/deploy-web/src/queries/useBalancesQuery.ts +++ b/deploy-web/src/queries/useBalancesQuery.ts @@ -5,15 +5,22 @@ import { useSettings } from "../context/SettingsProvider"; import { ApiUrlService } from "@src/utils/apiUtils"; import { Balances } from "@src/types"; import { uAktDenom, usdcIbcDenom } from "@src/utils/constants"; +import { + RestApiBalancesResponseType, + RestApiDelegationsType, + RestApiRedelegationsResponseType, + RestApiRewardsResponseType, + RestApiUnbondingsResponseType +} from "@src/types/balances"; // Account balances async function getBalances(apiEndpoint: string, address: string): Promise { if (!address) return {} as Balances; - const balancePromise = axios.get(ApiUrlService.balance(apiEndpoint, address)); - const rewardsPromise = axios.get(ApiUrlService.rewards(apiEndpoint, address)); - const redelegationsPromise = axios.get(ApiUrlService.redelegations(apiEndpoint, address)); - const unbondingsPromise = axios.get(ApiUrlService.unbonding(apiEndpoint, address)); + const balancePromise = axios.get(ApiUrlService.balance(apiEndpoint, address)); + const rewardsPromise = axios.get(ApiUrlService.rewards(apiEndpoint, address)); + const redelegationsPromise = axios.get(ApiUrlService.redelegations(apiEndpoint, address)); + const unbondingsPromise = axios.get(ApiUrlService.unbonding(apiEndpoint, address)); const [balanceResponse, rewardsResponse, redelegationsResponse, unbondingsResponse] = await Promise.all([ balancePromise, @@ -51,7 +58,7 @@ async function getBalances(apiEndpoint: string, address: string): Promise(ApiUrlService.delegations(apiEndpoint, address)); const delegationsData = delegationsResponse.data; delegations = delegationsData.delegation_responses.some(b => b.balance.denom === uAktDenom) diff --git a/deploy-web/src/queries/useDeploymentQuery.ts b/deploy-web/src/queries/useDeploymentQuery.ts index 231a941a4..1cdff36cc 100644 --- a/deploy-web/src/queries/useDeploymentQuery.ts +++ b/deploy-web/src/queries/useDeploymentQuery.ts @@ -6,7 +6,7 @@ import { ApiUrlService, loadWithPagination } from "@src/utils/apiUtils"; import { deploymentToDto } from "@src/utils/deploymentDetailUtils"; // Deployment list -async function getDeploymentList(apiEndpoint, address) { +async function getDeploymentList(apiEndpoint: string, address: string) { if (!address) return []; const deployments = await loadWithPagination(ApiUrlService.deploymentList(apiEndpoint, address), "deployments", 1000); @@ -14,13 +14,13 @@ async function getDeploymentList(apiEndpoint, address) { return deployments.map(d => deploymentToDto(d)); } -export function useDeploymentList(address, options) { +export function useDeploymentList(address: string, options) { const { settings } = useSettings(); return useQuery(QueryKeys.getDeploymentListKey(address), () => getDeploymentList(settings.apiEndpoint, address), options); } // Deployment detail -async function getDeploymentDetail(apiEndpoint, address, dseq) { +async function getDeploymentDetail(apiEndpoint: string, address: string, dseq: string) { if (!address) return null; const response = await axios.get(ApiUrlService.deploymentDetail(apiEndpoint, address, dseq)); @@ -28,7 +28,7 @@ async function getDeploymentDetail(apiEndpoint, address, dseq) { return deploymentToDto(response.data); } -export function useDeploymentDetail(address, dseq, options) { +export function useDeploymentDetail(address: string, dseq: string, options) { const { settings } = useSettings(); return useQuery(QueryKeys.getDeploymentDetailKey(address, dseq), () => getDeploymentDetail(settings.apiEndpoint, address, dseq), options); } diff --git a/deploy-web/src/queries/useLeaseQuery.ts b/deploy-web/src/queries/useLeaseQuery.ts index 4e9b90c2e..0c333ab11 100644 --- a/deploy-web/src/queries/useLeaseQuery.ts +++ b/deploy-web/src/queries/useLeaseQuery.ts @@ -6,9 +6,11 @@ import { leaseToDto } from "@src/utils/deploymentDetailUtils"; import { ApiUrlService, loadWithPagination } from "@src/utils/apiUtils"; import axios from "axios"; import { PROVIDER_PROXY_URL } from "@src/utils/constants"; +import { LeaseDto } from "@src/types/deployment"; +import { LocalCert } from "@src/context/CertificateProvider/CertificateProviderContext"; // Leases -async function getDeploymentLeases(apiEndpoint, address, deployment) { +async function getDeploymentLeases(apiEndpoint: string, address: string, deployment) { if (!address) { return null; } @@ -20,13 +22,13 @@ async function getDeploymentLeases(apiEndpoint, address, deployment) { return leases; } -export function useDeploymentLeaseList(address, deployment, options) { +export function useDeploymentLeaseList(address: string, deployment, options) { const { settings } = useSettings(); return useQuery(QueryKeys.getLeasesKey(address, deployment?.dseq), () => getDeploymentLeases(settings.apiEndpoint, address, deployment), options); } -async function getAllLeases(apiEndpoint, address, deployment?) { +async function getAllLeases(apiEndpoint: string, address: string, deployment?) { if (!address) { return null; } @@ -38,12 +40,12 @@ async function getAllLeases(apiEndpoint, address, deployment?) { return leases; } -export function useAllLeases(address, options = {}) { +export function useAllLeases(address: string, options = {}) { const { settings } = useSettings(); return useQuery(QueryKeys.getAllLeasesKey(address), () => getAllLeases(settings.apiEndpoint, address), options); } -async function getLeaseStatus(providerUri, lease, localCert) { +async function getLeaseStatus(providerUri: string, lease: LeaseDto, localCert: LocalCert) { if (!providerUri) return null; const leaseStatusPath = `${providerUri}/lease/${lease.dseq}/${lease.gseq}/${lease.oseq}/status`; @@ -57,7 +59,7 @@ async function getLeaseStatus(providerUri, lease, localCert) { return response.data; } -export function useLeaseStatus(providerUri, lease, options) { +export function useLeaseStatus(providerUri: string, lease: LeaseDto, options) { const { localCert } = useCertificate(); - return useQuery(QueryKeys.getLeaseStatusKey(lease.dseq, lease.gseq, lease.oseq), () => getLeaseStatus(providerUri, lease, localCert), options); + return useQuery(QueryKeys.getLeaseStatusKey(lease?.dseq, lease?.gseq, lease?.oseq), () => getLeaseStatus(providerUri, lease, localCert), options); } diff --git a/deploy-web/src/types/balances.ts b/deploy-web/src/types/balances.ts new file mode 100644 index 000000000..eeeaa5306 --- /dev/null +++ b/deploy-web/src/types/balances.ts @@ -0,0 +1,88 @@ +import { Coin } from "@cosmjs/stargate"; + +export type RestApiBalancesResponseType = { + balances: Coin[]; + pagination: { + next_key: string; + total: string; + }; +}; + +export type RestApiRewardsResponseType = { + rewards: { + reward: Coin[]; + validator_address: string; + }[]; + total: Coin[]; +}; + +export type RestApiRedelegationsResponseType = { + redelegation_responses: { + redelegation: { + delegator_address: string; + validator_src_address: string; + validator_dst_address: string; + entries: [ + { + creation_height: string; + completion_time: string; + initial_balance: string; + shares_dst: string; + } + ]; + }; + entries: [ + { + redelegation_entry: { + creation_height: string; + completion_time: string; + initial_balance: string; + shares_dst: string; + }; + balance: string; + } + ]; + }[]; + pagination: { + next_key: string; + total: string; + }; +}; + +export type RestApiUnbondingsResponseType = { + unbonding_responses: [ + { + delegator_address: string; + validator_address: string; + entries: [ + { + creation_height: string; + completion_time: string; + initial_balance: string; + balance: string; + } + ]; + } + ]; + pagination: { + next_key: string; + total: string; + }; +}; + +export type RestApiDelegationsType = { + delegation_responses: [ + { + delegation: { + delegator_address: string; + validator_address: string; + shares: string; + }; + balance: Coin; + } + ]; + pagination: { + next_key: string; + total: string; + }; +}; diff --git a/deploy-web/src/types/certificate.ts b/deploy-web/src/types/certificate.ts new file mode 100644 index 000000000..1b9c79b0c --- /dev/null +++ b/deploy-web/src/types/certificate.ts @@ -0,0 +1,14 @@ +export type RestApiCertificatesResponseType = { + certificates: { + certificate: { + cert: string; + pubkey: string; + state: string; + }; + serial: string; + }[]; + pagination: { + next_key: string; + total: string; + }; +}; diff --git a/deploy-web/src/utils/TransactionMessageData.ts b/deploy-web/src/utils/TransactionMessageData.ts index b97013783..3ce867cc6 100644 --- a/deploy-web/src/utils/TransactionMessageData.ts +++ b/deploy-web/src/utils/TransactionMessageData.ts @@ -1,4 +1,5 @@ import { networkVersion } from "./constants"; +import { BidDto } from "@src/types/deployment"; export function setMessageTypes() { TransactionMessageData.Types.MSG_CLOSE_DEPLOYMENT = `/akash.deployment.${networkVersion}.MsgCloseDeployment`; @@ -32,7 +33,7 @@ export class TransactionMessageData { MSG_REVOKE: "/cosmos.authz.v1beta1.MsgRevoke" }; - static getRevokeCertificateMsg(address, serial) { + static getRevokeCertificateMsg(address: string, serial: string) { const message = { typeUrl: TransactionMessageData.Types.MSG_REVOKE_CERTIFICATE, value: { @@ -46,7 +47,7 @@ export class TransactionMessageData { return message; } - static getCreateCertificateMsg(address, crtpem, pubpem) { + static getCreateCertificateMsg(address: string, crtpem: string, pubpem: string) { const message = { typeUrl: TransactionMessageData.Types.MSG_CREATE_CERTIFICATE, value: { @@ -59,7 +60,7 @@ export class TransactionMessageData { return message; } - static getCreateLeaseMsg(bid) { + static getCreateLeaseMsg(bid: BidDto) { const message = { typeUrl: TransactionMessageData.Types.MSG_CREATE_LEASE, value: { @@ -122,7 +123,7 @@ export class TransactionMessageData { return message; } - static getCloseDeploymentMsg(address, dseq) { + static getCloseDeploymentMsg(address: string, dseq: string) { const message = { typeUrl: TransactionMessageData.Types.MSG_CLOSE_DEPLOYMENT, value: { @@ -136,7 +137,7 @@ export class TransactionMessageData { return message; } - static getSendTokensMsg(address, recipient, amount) { + static getSendTokensMsg(address: string, recipient: string, amount: number) { const message = { typeUrl: TransactionMessageData.Types.MSG_SEND_TOKENS, value: { diff --git a/deploy-web/src/utils/analytics.ts b/deploy-web/src/utils/analytics.ts index 43edd943a..8fa323afb 100644 --- a/deploy-web/src/utils/analytics.ts +++ b/deploy-web/src/utils/analytics.ts @@ -20,9 +20,6 @@ export enum AnalyticsEvents { AUTHORIZE_SPEND = "authorize_spend", NAVIGATE_TAB = "navigate_tab_", // Append tab - ADD_ALERT_SEND_TOKENS = "add_alert_send_tokens", - ADD_ALERT_RECEIVE_TOKENS = "add_alert_receive_tokens", - // SDL Builder DEPLOY_SDL = "deploy_sdl", IMPORT_SDL = "import_sdl", diff --git a/deploy-web/src/utils/apiUtils.ts b/deploy-web/src/utils/apiUtils.ts index a52b43b3b..805cde45a 100644 --- a/deploy-web/src/utils/apiUtils.ts +++ b/deploy-web/src/utils/apiUtils.ts @@ -3,40 +3,40 @@ import axios from "axios"; import { appendSearchParams } from "./urlUtils"; export class ApiUrlService { - static deploymentList(apiEndpoint, address) { + static deploymentList(apiEndpoint: string, address: string) { return `${apiEndpoint}/akash/deployment/${networkVersion}/deployments/list?filters.owner=${address}`; } - static deploymentDetail(apiEndpoint, address, dseq) { + static deploymentDetail(apiEndpoint: string, address: string, dseq: string) { return `${apiEndpoint}/akash/deployment/${networkVersion}/deployments/info?id.owner=${address}&id.dseq=${dseq}`; } - static bidList(apiEndpoint, address, dseq) { + static bidList(apiEndpoint: string, address: string, dseq: string) { return `${apiEndpoint}/akash/market/${networkVersion}/bids/list?filters.owner=${address}&filters.dseq=${dseq}`; } - static leaseList(apiEndpoint, address, dseq) { + static leaseList(apiEndpoint: string, address: string, dseq: string) { return `${apiEndpoint}/akash/market/${networkVersion}/leases/list?filters.owner=${address}${dseq ? "&filters.dseq=" + dseq : ""}`; } - static providers(apiEndpoint) { + static providers(apiEndpoint: string) { return `${apiEndpoint}/akash/provider/${networkVersion}/providers`; } - static providerDetail(apiEndpoint, owner) { + static providerDetail(apiEndpoint: string, owner: string) { return `${apiEndpoint}/akash/provider/${networkVersion}/providers/${owner}`; } - static block(apiEndpoint, id) { + static block(apiEndpoint: string, id: string) { return `${apiEndpoint}/blocks/${id}`; } - static balance(apiEndpoint, address) { + static balance(apiEndpoint: string, address: string) { return `${apiEndpoint}/cosmos/bank/v1beta1/balances/${address}`; } - static rewards(apiEndpoint, address) { + static rewards(apiEndpoint: string, address: string) { return `${apiEndpoint}/cosmos/distribution/v1beta1/delegators/${address}/rewards`; } - static redelegations(apiEndpoint, address) { + static redelegations(apiEndpoint: string, address: string) { return `${apiEndpoint}/cosmos/staking/v1beta1/delegators/${address}/redelegations`; } - static delegations(apiEndpoint, address) { + static delegations(apiEndpoint: string, address: string) { return `${apiEndpoint}/cosmos/staking/v1beta1/delegations/${address}`; } - static unbonding(apiEndpoint, address) { + static unbonding(apiEndpoint: string, address: string) { return `${apiEndpoint}/cosmos/staking/v1beta1/delegators/${address}/unbonding_delegations`; } static granteeGrants(apiEndpoint: string, address: string) { @@ -114,7 +114,7 @@ export class ApiUrlService { } } -export async function loadWithPagination(baseUrl, dataKey, limit) { +export async function loadWithPagination(baseUrl: string, dataKey: string, limit: number) { let items = []; let nextKey = null; // let callCount = 1; @@ -144,6 +144,6 @@ export async function loadWithPagination(baseUrl, dataKey, limit) { return items.filter(item => item); } -function hasQueryParam(url) { +function hasQueryParam(url: string) { return /[?&]/gm.test(url); } diff --git a/deploy-web/src/utils/certificateUtils.ts b/deploy-web/src/utils/certificateUtils.ts index 478e6eaec..3a586a050 100644 --- a/deploy-web/src/utils/certificateUtils.ts +++ b/deploy-web/src/utils/certificateUtils.ts @@ -1,6 +1,6 @@ import rs from "jsrsasign"; -export async function openCert(certPem, encryptedKeyPem) { +export async function openCert(certPem: string, encryptedKeyPem: string) { if (!certPem || !encryptedKeyPem) return null; const key = rs.KEYUTIL.getKeyFromPlainPrivatePKCS8PEM(encryptedKeyPem); diff --git a/deploy-web/src/utils/deploymentData/helpers.ts b/deploy-web/src/utils/deploymentData/helpers.ts index 2080d9198..6b7ac3d52 100644 --- a/deploy-web/src/utils/deploymentData/helpers.ts +++ b/deploy-web/src/utils/deploymentData/helpers.ts @@ -30,7 +30,7 @@ const specSuffixes = { Eb: 1000 * 1000 * 1000 * 1000 * 1000 * 1000 }; -export async function getCurrentHeight(apiEndpoint) { +export async function getCurrentHeight(apiEndpoint: string) { const response = await axios.get(`${apiEndpoint}/blocks/latest`); const data = response.data; @@ -38,9 +38,9 @@ export async function getCurrentHeight(apiEndpoint) { return height; } -export function parseSizeStr(str) { +export function parseSizeStr(str: string) { try { - const suffix = Object.keys(specSuffixes).find(s => str.toString().toLowerCase().endsWith(s.toLowerCase())); + const suffix = Object.keys(specSuffixes).find(s => str.toLowerCase().endsWith(s.toLowerCase())); if (suffix) { const suffixPos = str.length - suffix.length; diff --git a/deploy-web/src/utils/deploymentData/index.ts b/deploy-web/src/utils/deploymentData/index.ts index 869a23797..0e32c65f2 100644 --- a/deploy-web/src/utils/deploymentData/index.ts +++ b/deploy-web/src/utils/deploymentData/index.ts @@ -4,7 +4,7 @@ import { mainnetId, testnetId, sandboxId } from "../constants"; export * from "./helpers"; export let deploymentData; -export let selectedNetworkId; +export let selectedNetworkId: string; export function initDeploymentData() { selectedNetworkId = localStorage.getItem("selectedNetworkId"); diff --git a/deploy-web/src/utils/deploymentData/v1beta2.ts b/deploy-web/src/utils/deploymentData/v1beta2.ts index 4715aa757..61dda74f7 100644 --- a/deploy-web/src/utils/deploymentData/v1beta2.ts +++ b/deploy-web/src/utils/deploymentData/v1beta2.ts @@ -1,7 +1,7 @@ import { CustomValidationError, ManifestVersion, getCurrentHeight, Manifest, DeploymentGroups, getSdl, parseSizeStr } from "./helpers"; import { defaultInitialDeposit } from "../constants"; import { stringToBoolean } from "../stringUtils"; -const path = require("path"); +import path from "path"; const endpointNameValidationRegex = /^[a-z]+[-_\da-z]+$/; const endpointKindIP = "ip"; diff --git a/deploy-web/src/utils/deploymentData/v1beta3.ts b/deploy-web/src/utils/deploymentData/v1beta3.ts index d80d54796..90fd37033 100644 --- a/deploy-web/src/utils/deploymentData/v1beta3.ts +++ b/deploy-web/src/utils/deploymentData/v1beta3.ts @@ -1,7 +1,7 @@ import { CustomValidationError, DeploymentGroups, Manifest, ManifestVersion, getCurrentHeight, getSdl, parseSizeStr } from "./helpers"; import { defaultInitialDeposit } from "../constants"; import { stringToBoolean } from "../stringUtils"; -const path = require("path"); +import path from "path"; const endpointNameValidationRegex = /^[a-z]+[-_\da-z]+$/; const endpointKindIP = "ip"; diff --git a/deploy-web/src/utils/deploymentDetailUtils.ts b/deploy-web/src/utils/deploymentDetailUtils.ts index 133ee0582..d5d488a02 100644 --- a/deploy-web/src/utils/deploymentDetailUtils.ts +++ b/deploy-web/src/utils/deploymentDetailUtils.ts @@ -1,7 +1,7 @@ import { DeploymentDto, LeaseDto, RpcDeployment, RpcLease } from "@src/types/deployment"; import { coinToUAkt } from "./priceUtils"; -export function deploymentResourceSum(deployment, resourceSelector) { +export function deploymentResourceSum(deployment: RpcDeployment, resourceSelector) { return deployment.groups.map(g => g.group_spec.resources.map(r => r.count * resourceSelector(r.resources)).reduce((a, b) => a + b)).reduce((a, b) => a + b); } @@ -37,8 +37,8 @@ export function deploymentToDto(d: RpcDeployment): DeploymentDto { }; } -export function convertToArrayIfNeeded(arrayOrItem) { - return arrayOrItem.map ? arrayOrItem : [arrayOrItem]; +export function convertToArrayIfNeeded(arrayOrItem: T | T[]) { + return Array.isArray(arrayOrItem) ? arrayOrItem : [arrayOrItem]; } export const getStorageAmount = resource => { diff --git a/deploy-web/src/utils/deploymentLocalDataUtils.ts b/deploy-web/src/utils/deploymentLocalDataUtils.ts index e4b72b92a..e974ab250 100644 --- a/deploy-web/src/utils/deploymentLocalDataUtils.ts +++ b/deploy-web/src/utils/deploymentLocalDataUtils.ts @@ -1,22 +1,29 @@ import { getSelectedStorageWallet } from "./walletUtils"; -export function getDeploymentLocalData(dseq) { +export type LocalDeploymentData = { + owner?: string; + name?: string; + manifest?: string; + manifestVersion?: string; +}; + +export function getDeploymentLocalData(dseq: string | number) { const selectedNetworkId = localStorage.getItem("selectedNetworkId"); const selectedWallet = getSelectedStorageWallet(); const dataStr = localStorage.getItem(`${selectedNetworkId}/${selectedWallet.address}/deployments/${dseq}.data`); if (!dataStr) return null; - const parsedData = JSON.parse(dataStr); + const parsedData = JSON.parse(dataStr) as LocalDeploymentData; return parsedData; } -export function saveDeploymentManifestAndName(dseq, manifest, version, address, name) { +export function saveDeploymentManifestAndName(dseq: string, manifest: string, version: string, address: string, name: string) { saveDeploymentManifest(dseq, manifest, version, address); updateDeploymentLocalData(dseq, { name: name }); } -export function saveDeploymentManifest(dseq, manifest, version, address) { +export function saveDeploymentManifest(dseq: string, manifest: string, version: string, address: string) { const data = getDeploymentLocalData(dseq) || {}; data.owner = address; data.manifest = manifest; @@ -29,7 +36,7 @@ export function saveDeploymentManifest(dseq, manifest, version, address) { localStorage.setItem(`${selectedNetworkId}/${selectedWallet.address}/deployments/${dseq}.data`, JSON.stringify(data)); } -export function updateDeploymentLocalData(dseq, data) { +export function updateDeploymentLocalData(dseq: string, data: LocalDeploymentData) { const oldData = getDeploymentLocalData(dseq) || {}; const newData = { ...oldData, ...data }; diff --git a/deploy-web/src/utils/deploymentUtils.ts b/deploy-web/src/utils/deploymentUtils.ts index 792208843..82e29b8cd 100644 --- a/deploy-web/src/utils/deploymentUtils.ts +++ b/deploy-web/src/utils/deploymentUtils.ts @@ -1,7 +1,8 @@ import axios from "axios"; import { PROVIDER_PROXY_URL } from "./constants"; +import { LocalCert } from "@src/context/CertificateProvider/CertificateProviderContext"; -export const sendManifestToProvider = async (providerInfo, manifest, dseq, localCert) => { +export const sendManifestToProvider = async (providerInfo, manifest, dseq: string, localCert: LocalCert) => { console.log("Sending manifest to " + providerInfo?.owner); let jsonStr = JSON.stringify(manifest); diff --git a/deploy-web/src/utils/priceUtils.ts b/deploy-web/src/utils/priceUtils.ts index e99472912..438db069a 100644 --- a/deploy-web/src/utils/priceUtils.ts +++ b/deploy-web/src/utils/priceUtils.ts @@ -1,10 +1,11 @@ import { useBlock } from "@src/queries/useBlocksQuery"; import add from "date-fns/add"; import { averageDaysInMonth } from "./dateUtils"; +import { Coin } from "@cosmjs/stargate"; export const averageBlockTime = 6.098; -export function uaktToAKT(amount, precision = 3) { +export function uaktToAKT(amount: number, precision: number = 3) { return Math.round((amount / 1000000 + Number.EPSILON) * Math.pow(10, precision)) / Math.pow(10, precision); } @@ -12,7 +13,7 @@ export function aktToUakt(amount: number | string) { return Math.round((typeof amount === "string" ? parseFloat(amount) : amount) * 1_000_000); } -export function coinToUAkt(coin: { denom: string; amount: string }) { +export function coinToUAkt(coin: Coin) { let uakt: number = null; if (coin.denom === "akt") { uakt = aktToUakt(parseFloat(coin.amount)); @@ -25,7 +26,7 @@ export function coinToUAkt(coin: { denom: string; amount: string }) { return uakt; } -export function coinToAkt(coin: { denom: string; amount: string }) { +export function coinToAkt(coin: Coin) { let akt: number = null; if (coin.denom === "akt") { akt = parseFloat(coin.amount); @@ -49,7 +50,7 @@ export function getTimeLeft(pricePerBlock: number, balance: number) { return add(new Date(timestamp), { seconds: blocksLeft * averageBlockTime }); } -export function useRealTimeLeft(pricePerBlock, balance, settledAt, createdAt) { +export function useRealTimeLeft(pricePerBlock: number, balance: number, settledAt: number, createdAt: number) { const { data: latestBlock } = useBlock("latest", { refetchInterval: 30000 }); diff --git a/deploy-web/src/utils/providerUtils.ts b/deploy-web/src/utils/providerUtils.ts index 525b80224..09d3ac43f 100644 --- a/deploy-web/src/utils/providerUtils.ts +++ b/deploy-web/src/utils/providerUtils.ts @@ -1,8 +1,11 @@ -import { ProviderDetail, ProviderStatus, ProviderStatusDto, ProviderVersion } from "@src/types/provider"; -import { roundDecimal } from "./mathHelpers"; +import { ProviderStatus, ProviderStatusDto, ProviderVersion } from "@src/types/provider"; import { ISnapshotMetadata, ProviderSnapshots } from "@src/types"; import { bytesToShrink } from "./unitUtils"; +export type LocalProviderData = { + favorites: string[]; +}; + export function providerStatusToDto(providerStatus: ProviderStatus, providerVersion: ProviderVersion): ProviderStatusDto { return { name: providerStatus.cluster_public_hostname, @@ -18,41 +21,6 @@ export function providerStatusToDto(providerStatus: ProviderStatus, providerVers }; } -function getStorageFromResource(resource) { - return Object.keys(resource).includes("storage_ephemeral") ? resource.storage_ephemeral : resource.storage; -} - -export function getTotalProviderResource(resources) { - const resourcesArr = resources?.nodes || resources; - - const result = resourcesArr - ?.map(x => { - return { - cpu: getCpuValue(x.cpu), - memory: getByteValue(x.memory), - storage: getByteValue(getStorageFromResource(x)) - }; - }) - .reduce((prev, current) => { - return { - cpu: prev?.cpu + current.cpu, - memory: prev?.memory + current.memory, - storage: prev?.storage + current.storage - }; - }); - - return result || { cpu: 0, memory: 0, storage: 0 }; -} - -function getCpuValue(cpu) { - const _cpu = typeof cpu === "number" ? cpu : parseInt(cpu.units.val); - return roundDecimal(_cpu / 1000, 1); -} - -function getByteValue(val) { - return typeof val === "number" ? val : parseInt(val.size.val); -} - export function getNetworkCapacityDto(networkCapacity) { return { ...networkCapacity, @@ -63,19 +31,19 @@ export function getNetworkCapacityDto(networkCapacity) { }; } -export function getProviderLocalData() { +export function getProviderLocalData(): LocalProviderData { const selectedNetworkId = localStorage.getItem("selectedNetworkId"); const dataStr = localStorage.getItem(`${selectedNetworkId}/provider.data`); if (!dataStr) { return { favorites: [] }; } - const parsedData = JSON.parse(dataStr); + const parsedData = JSON.parse(dataStr) as LocalProviderData; return parsedData; } -export function updateProviderLocalData(data) { +export function updateProviderLocalData(data: LocalProviderData) { const oldData = getProviderLocalData(); const newData = { ...oldData, ...data }; @@ -83,7 +51,7 @@ export function updateProviderLocalData(data) { localStorage.setItem(`${selectedNetworkId}/provider.data`, JSON.stringify(newData)); } -export const getSnapshotMetadata = (snapshot?: ProviderSnapshots): { unitFn: (number) => ISnapshotMetadata; legend?: string } => { +export const getSnapshotMetadata = (snapshot?: ProviderSnapshots): { unitFn: (number: number) => ISnapshotMetadata; legend?: string } => { switch (snapshot) { case ProviderSnapshots.cpu: return { diff --git a/deploy-web/src/utils/stringUtils.ts b/deploy-web/src/utils/stringUtils.ts index 903052d35..67a56e854 100644 --- a/deploy-web/src/utils/stringUtils.ts +++ b/deploy-web/src/utils/stringUtils.ts @@ -1,4 +1,4 @@ -export function stringToBoolean(str = "") { +export function stringToBoolean(str: string) { switch (str.toLowerCase()) { case "false": case "no": @@ -14,19 +14,16 @@ export function capitalizeFirstLetter(string: string) { return string.charAt(0).toUpperCase() + string.slice(1); } -export function isUrl(val) { - let url; - +export function isUrl(val: string) { try { - url = new URL(val); + const url = new URL(val); + return url.protocol === "http:" || url.protocol === "https:"; } catch (_) { return false; } - - return url.protocol === "http:" || url.protocol === "https:"; } -export function selectText(node) { +export function selectText(node: HTMLElement) { if ((document.body as any).createTextRange) { const range = (document.body as any).createTextRange(); range.moveToElementText(node); diff --git a/deploy-web/src/utils/urlUtils.ts b/deploy-web/src/utils/urlUtils.ts index a8ab0de24..40f6769b0 100644 --- a/deploy-web/src/utils/urlUtils.ts +++ b/deploy-web/src/utils/urlUtils.ts @@ -62,11 +62,11 @@ export class UrlService { // Deploy static deploymentList = () => `/deployments`; - static deploymentDetails = (dseq, tab?, logsMode?) => `/deployments/${dseq}${appendSearchParams({ tab, logsMode })}`; + static deploymentDetails = (dseq: string, tab?: string, logsMode?: string) => `/deployments/${dseq}${appendSearchParams({ tab, logsMode })}`; static publicDeploymentDetails = (owner: string, dseq: string) => `/deployment/${owner}/${dseq}${appendSearchParams({ network: getSelectedNetworkQueryParam() })}`; static templates = (category?: string, search?: string) => `/templates${appendSearchParams({ category, search })}`; - static templateDetails = templateId => `/templates/${templateId}`; + static templateDetails = (templateId: string) => `/templates/${templateId}`; static providers = () => "/providers"; static providerDetail = (owner: string) => `/providers/${owner}`; static providerDetailLeases = (owner: string) => `/providers/${owner}/leases`; diff --git a/deploy-web/src/utils/walletUtils.ts b/deploy-web/src/utils/walletUtils.ts index bcffed8a7..fc0c68a7e 100644 --- a/deploy-web/src/utils/walletUtils.ts +++ b/deploy-web/src/utils/walletUtils.ts @@ -1,5 +1,13 @@ import { mainnetId } from "./constants"; +export type LocalWalletDataType = { + address: string; + cert: string; + certKey: string; + name: string; + selected: boolean; +}; + export const useStorageWallets = () => { const wallets = getStorageWallets(); @@ -9,17 +17,17 @@ export const useStorageWallets = () => { export function getSelectedStorageWallet() { const wallets = getStorageWallets(); - return wallets.find(w => w.selected) || wallets[0] || {}; + return wallets.find(w => w.selected) ?? wallets[0] ?? null; } export function getStorageWallets() { const selectedNetworkId = localStorage.getItem("selectedNetworkId") || mainnetId; - const wallets = JSON.parse(localStorage.getItem(`${selectedNetworkId}/wallets`)); + const wallets = JSON.parse(localStorage.getItem(`${selectedNetworkId}/wallets`)) as LocalWalletDataType[]; return wallets || []; } -export function updateWallet(address, func) { +export function updateWallet(address: string, func: (w: LocalWalletDataType) => LocalWalletDataType) { const wallets = getStorageWallets(); let wallet = wallets.find(w => w.address === address); wallet = func(wallet); @@ -28,12 +36,12 @@ export function updateWallet(address, func) { updateStorageWallets(newWallets); } -export function updateStorageWallets(wallets) { +export function updateStorageWallets(wallets: LocalWalletDataType[]) { const selectedNetworkId = localStorage.getItem("selectedNetworkId") || mainnetId; localStorage.setItem(`${selectedNetworkId}/wallets`, JSON.stringify(wallets)); } -export function deleteWalletFromStorage(address, deleteDeployments) { +export function deleteWalletFromStorage(address: string, deleteDeployments: boolean) { const selectedNetworkId = localStorage.getItem("selectedNetworkId") || mainnetId; const wallets = getStorageWallets(); const newWallets = wallets.filter(w => w.address !== address).map((w, i) => ({ ...w, selected: i === 0 })); @@ -57,7 +65,7 @@ export function useSelectedWalletFromStorage() { return getSelectedStorageWallet(); } -export function updateLocalStorageWalletName(address, name) { +export function updateLocalStorageWalletName(address: string, name: string) { updateWallet(address, wallet => { return { ...wallet, name }; }); From 4b654c483191812964fefa3ca249370a7037a14b Mon Sep 17 00:00:00 2001 From: Redm4x Date: Thu, 17 Aug 2023 11:40:28 -0400 Subject: [PATCH 4/7] Add env var for Rest Api url in api --- api/README.md | 5 ++++- api/src/providers/apiNodeProvider.ts | 6 ++++-- api/src/shared/utils/env.ts | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/api/README.md b/api/README.md index 962897ef0..e556296c6 100644 --- a/api/README.md +++ b/api/README.md @@ -20,13 +20,16 @@ When running the api locally the following environment variables can be set in a |Name|Value|Note| |-|-|- +Network|`mainnet` or `testnet`|Specify if the api should be in mainnet or testnet mode. Default: `mainnet`. +RestApiNodeUrl|ex: `"https://api.akashnet.net"`|Rest api to use. Will default to `"https://rest.cosmos.directory/akash"` for mainnet and `"https://api.testnet-02.aksh.pw:443"` for testnet. HealthchecksEnabled|`true` or `false`|Specify if the [Scheduler](./src/index.ts#L42) should send health check pings. SentryDSN|ex: `"https://1234...789@z645.ingest.sentry.io/1234"`|[Sentry DSN](https://docs.sentry.io/product/sentry-basics/dsn-explainer/) used when [initializing](./src/index.ts#L29) Sentry AkashDatabaseCS|ex: `postgres://user:password@localhost:5432/cloudmos-akash`|Akash Database Connection String +AkashTestnetDatabaseCS|ex: `postgres://user:password@localhost:5432/cloudmos-akash-testnet`|Akash Testnet Database Connection String UserDatabaseCS|ex: `postgres://user:password@localhost:5432/cloudmos-users`|User Database Connection String Auth0JWKSUri|ex: `'https://1a2b3c.us.auth0.com/.well-known/jwks.json'`| Auth0Audience|ex: `'https://api.cloudmos.io'` Auth0Issuer|ex: `'https://dev-5aprb0lr.us.auth0.com/'` Auth0Issuer|ex: `'https://auth.cloudmos.io/'` StripeSecretKey|ex: `sk_test_12aw315wdawd3...293d12d32df8jf` -WebsiteUrl|`http://localhost:3001` \ No newline at end of file +WebsiteUrl|`http://localhost:3001` diff --git a/api/src/providers/apiNodeProvider.ts b/api/src/providers/apiNodeProvider.ts index 8a9f65fa1..b2e0a78b6 100644 --- a/api/src/providers/apiNodeProvider.ts +++ b/api/src/providers/apiNodeProvider.ts @@ -10,9 +10,11 @@ import { Validator } from "@shared/dbSchemas/base"; import { Op } from "sequelize"; import { Provider, ProviderAttribute } from "@shared/dbSchemas/akash"; import { cacheKeys, cacheResponse } from "@src/caching/helpers"; +import { env } from "@src/shared/utils/env"; -const apiNodeUrl = process.env.Network === "testnet" ? "https://api.testnet-02.aksh.pw:443" : "https://rest.cosmos.directory/akash"; -const betaTypeVersion = process.env.Network === "testnet" ? "v1beta3" : "v1beta2"; +const defaultNodeUrl = env.Network === "testnet" ? "https://api.testnet-02.aksh.pw:443" : "https://rest.cosmos.directory/akash"; +const apiNodeUrl = env.RestApiNodeUrl ?? defaultNodeUrl; +const betaTypeVersion = env.Network === "testnet" ? "v1beta3" : "v1beta2"; export async function getChainStats() { const result: { communityPool: number; inflation: number; communityTax: number; bondedTokens: number; totalSupply: number } = await cacheResponse( diff --git a/api/src/shared/utils/env.ts b/api/src/shared/utils/env.ts index 8ff23fbc5..ce92ca895 100644 --- a/api/src/shared/utils/env.ts +++ b/api/src/shared/utils/env.ts @@ -11,6 +11,7 @@ export const env = { AkashTestnetDatabaseCS: process.env.AkashTestnetDatabaseCS, UserDatabaseCS: process.env.UserDatabaseCS, Network: process.env.Network ?? "mainnet", + RestApiNodeUrl: process.env.RestApiNodeUrl, AkashlyticsGithubPAT: process.env.AkashlyticsGithubPAT, Auth0JWKSUri: process.env.Auth0JWKSUri, Auth0Audience: process.env.Auth0Audience, From 770af5e92edc0ba2f7b088cba9deb5de345d08fc Mon Sep 17 00:00:00 2001 From: Redm4x Date: Fri, 18 Aug 2023 10:37:33 -0400 Subject: [PATCH 5/7] Fix bug created in earlier commit --- deploy-web/src/utils/stringUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy-web/src/utils/stringUtils.ts b/deploy-web/src/utils/stringUtils.ts index 67a56e854..7b4ab569b 100644 --- a/deploy-web/src/utils/stringUtils.ts +++ b/deploy-web/src/utils/stringUtils.ts @@ -1,4 +1,4 @@ -export function stringToBoolean(str: string) { +export function stringToBoolean(str: string = "") { switch (str.toLowerCase()) { case "false": case "no": From b6b6a79f3ccdfa793baa72aeda376d97ad78fb12 Mon Sep 17 00:00:00 2001 From: Redm4x Date: Fri, 18 Aug 2023 10:43:58 -0400 Subject: [PATCH 6/7] Add typing and show 404 if deployment is not found --- .../newDeploymentWizard/ManifestEdit.tsx | 7 +++--- deploy-web/src/pages/404.tsx | 2 +- deploy-web/src/pages/deployments/[dseq].tsx | 23 +++++++++++++++++-- deploy-web/src/utils/certificateUtils.ts | 6 ++--- .../src/utils/deploymentLocalDataUtils.ts | 3 +++ 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/deploy-web/src/components/newDeploymentWizard/ManifestEdit.tsx b/deploy-web/src/components/newDeploymentWizard/ManifestEdit.tsx index b22a70dd5..1583a24dd 100644 --- a/deploy-web/src/components/newDeploymentWizard/ManifestEdit.tsx +++ b/deploy-web/src/components/newDeploymentWizard/ManifestEdit.tsx @@ -151,12 +151,12 @@ export const ManifestEdit: React.FunctionComponent = ({ editedManifest, s setIsDepositingDeployment(true); }; - const onDeploymentDeposit = async (deposit, depositorAddress) => { + const onDeploymentDeposit = async (deposit: number, depositorAddress: string) => { setIsDepositingDeployment(false); await handleCreateClick(deposit, depositorAddress); }; - async function handleCreateClick(deposit, depositorAddress) { + async function handleCreateClick(deposit: number, depositorAddress: string) { setIsCreatingDeployment(true); const dd = await createAndValidateDeploymentData(editedManifest, null, deposit, depositorAddress); @@ -170,7 +170,8 @@ export const ManifestEdit: React.FunctionComponent = ({ editedManifest, s try { const messages = []; const hasValidCert = isCertificateValidated && isLocalCertificateValidated; - let _crtpem, _encryptedKey; + let _crtpem: string; + let _encryptedKey: string; // Create a cert if the user doesn't have one if (!hasValidCert) { diff --git a/deploy-web/src/pages/404.tsx b/deploy-web/src/pages/404.tsx index 8b4713d42..85050e116 100644 --- a/deploy-web/src/pages/404.tsx +++ b/deploy-web/src/pages/404.tsx @@ -20,7 +20,7 @@ const FourOhFour: React.FunctionComponent = ({}) => { - + 404 diff --git a/deploy-web/src/pages/deployments/[dseq].tsx b/deploy-web/src/pages/deployments/[dseq].tsx index 6ebeb1ca2..88bef3dce 100644 --- a/deploy-web/src/pages/deployments/[dseq].tsx +++ b/deploy-web/src/pages/deployments/[dseq].tsx @@ -3,7 +3,7 @@ import Layout from "@src/components/layout/Layout"; import { NextSeo } from "next-seo"; import { DeploymentDetailTopBar } from "@src/components/deploymentDetail/DeploymentDetailTopBar"; import { DeploymentSubHeader } from "@src/components/deploymentDetail/DeploymentSubHeader"; -import { Alert, Box, Button, CircularProgress, Tab, Tabs } from "@mui/material"; +import { Alert, Box, Button, CircularProgress, Tab, Tabs, Typography } from "@mui/material"; import { LeaseRow } from "@src/components/deploymentDetail/LeaseRow"; import { useRouter } from "next/router"; import { createRef, useEffect, useState } from "react"; @@ -22,6 +22,8 @@ import { AnalyticsEvents } from "@src/utils/analytics"; import { RouteStepKeys } from "@src/utils/constants"; import { useSettings } from "@src/context/SettingsProvider"; import PageContainer from "@src/components/shared/PageContainer"; +import Link from "next/link"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; type Props = { dseq: string; @@ -52,7 +54,8 @@ const DeploymentDetailPage: React.FunctionComponent<Props> = ({ dseq }) => { const { data: deployment, isFetching: isLoadingDeployment, - refetch: getDeploymentDetail + refetch: getDeploymentDetail, + error: deploymentError } = useDeploymentDetail(address, dseq, { enabled: false, onSuccess: _deploymentDetail => { @@ -92,6 +95,7 @@ const DeploymentDetailPage: React.FunctionComponent<Props> = ({ dseq }) => { } } }); + const isDeploymentNotFound = deploymentError && (deploymentError as any).response?.data?.message?.includes("Deployment not found"); const hasLeases = leases && leases.length > 0; const { isLocalCertMatching, localCert, isCreatingCert, createCertificate } = useCertificate(); const [deploymentManifest, setDeploymentManifest] = useState(null); @@ -159,6 +163,21 @@ const DeploymentDetailPage: React.FunctionComponent<Props> = ({ dseq }) => { deployment={deployment} /> + {isDeploymentNotFound && ( + <Box sx={{ textAlign: "center", marginTop: 10 }}> + <Typography variant="h1">404</Typography> + <Typography variant="subtitle1">This deployment does not exist or it was created using another wallet.</Typography> + <Box sx={{ paddingTop: "1rem" }}> + <Link href={UrlService.home()} passHref> + <Button variant="contained" color="secondary" sx={{ display: "inline-flex", alignItems: "center", textTransform: "initial" }}> + Go to homepage  + <ArrowForwardIcon fontSize="small" /> + </Button> + </Link> + </Box> + </Box> + )} + {deployment && ( <> <DeploymentSubHeader deployment={deployment} leases={leases} /> diff --git a/deploy-web/src/utils/certificateUtils.ts b/deploy-web/src/utils/certificateUtils.ts index 3a586a050..5b4b45db7 100644 --- a/deploy-web/src/utils/certificateUtils.ts +++ b/deploy-web/src/utils/certificateUtils.ts @@ -44,9 +44,9 @@ export const generateCertificate = (address: string) => { const prv = kp.prvKeyObj; const pub = kp.pubKeyObj; - const encryptedKey = rs.KEYUTIL.getPEM(prv, "PKCS8PRV"); + const encryptedKey = rs.KEYUTIL.getPEM(prv, "PKCS8PRV") as string; - const pubpem = rs.KEYUTIL.getPEM(pub, "PKCS8PUB").replaceAll("PUBLIC KEY", "EC PUBLIC KEY"); + const pubpem = rs.KEYUTIL.getPEM(pub, "PKCS8PUB").replaceAll("PUBLIC KEY", "EC PUBLIC KEY") as string; // STEP2. specify certificate parameters const cert = new rs.KJUR.asn1.x509.Certificate({ @@ -70,7 +70,7 @@ export const generateCertificate = (address: string) => { cakey: prv // can specify private key object or PEM string }); - const crtpem = cert.getPEM(); + const crtpem = cert.getPEM() as string; return { cert, crtpem, pubpem, encryptedKey }; }; diff --git a/deploy-web/src/utils/deploymentLocalDataUtils.ts b/deploy-web/src/utils/deploymentLocalDataUtils.ts index e974ab250..95fe525b4 100644 --- a/deploy-web/src/utils/deploymentLocalDataUtils.ts +++ b/deploy-web/src/utils/deploymentLocalDataUtils.ts @@ -10,6 +10,9 @@ export type LocalDeploymentData = { export function getDeploymentLocalData(dseq: string | number) { const selectedNetworkId = localStorage.getItem("selectedNetworkId"); const selectedWallet = getSelectedStorageWallet(); + + if (!selectedWallet) return null; + const dataStr = localStorage.getItem(`${selectedNetworkId}/${selectedWallet.address}/deployments/${dseq}.data`); if (!dataStr) return null; From b7ca52103435c63425e37a485a86cd3cf9841d28 Mon Sep 17 00:00:00 2001 From: Redm4x <max_maxime_max@hotmail.com> Date: Thu, 31 Aug 2023 08:11:05 -0400 Subject: [PATCH 7/7] Fixes --- .../src/components/deploymentDetail/DeploymentSubHeader.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy-web/src/components/deploymentDetail/DeploymentSubHeader.tsx b/deploy-web/src/components/deploymentDetail/DeploymentSubHeader.tsx index fc7b1045c..6e79a49db 100644 --- a/deploy-web/src/components/deploymentDetail/DeploymentSubHeader.tsx +++ b/deploy-web/src/components/deploymentDetail/DeploymentSubHeader.tsx @@ -29,7 +29,7 @@ export const DeploymentSubHeader: React.FunctionComponent<Props> = ({ deployment const { classes } = useStyles(); const hasLeases = leases && leases.length > 0; const deploymentCost = hasLeases ? leases.reduce((prev, current) => prev + parseFloat(current.price.amount), 0) : 0; - const realTimeLeft = useRealTimeLeft(deploymentCost, deployment.escrowBalance, deployment.escrowAccount.settled_at, deployment.createdAt); + const realTimeLeft = useRealTimeLeft(deploymentCost, deployment.escrowBalance, parseFloat(deployment.escrowAccount.settled_at), deployment.createdAt); const avgCost = uaktToAKT(getAvgCostPerMonth(deploymentCost)); const isActive = deployment.state === "active"; const hasActiveLeases = hasLeases && leases.some(l => l.state === "active"); @@ -99,12 +99,12 @@ export const DeploymentSubHeader: React.FunctionComponent<Props> = ({ deployment <Box sx={{ display: "flex", alignItems: "center" }}> <PriceValue denom={deployment.escrowAccount.balance.denom} - value={uaktToAKT(isActive && hasActiveLeases ? realTimeLeft?.amountSpent : deployment.transferred.amount, 6)} + value={uaktToAKT(isActive && hasActiveLeases ? realTimeLeft?.amountSpent : parseFloat(deployment.transferred.amount), 6)} /> <CustomTooltip arrow - title={<span>{uaktToAKT(isActive && hasActiveLeases ? realTimeLeft?.amountSpent : deployment.transferred.amount, 6)} AKT</span>} + title={<span>{uaktToAKT(isActive && hasActiveLeases ? realTimeLeft?.amountSpent : parseFloat(deployment.transferred.amount), 6)} AKT</span>} > <InfoIcon fontSize="small" color="disabled" sx={{ marginLeft: ".5rem" }} /> </CustomTooltip>