diff --git a/apps/api/src/billing/services/anonymous-validate/anonymous-validate.ts b/apps/api/src/billing/services/anonymous-validate/anonymous-validate.ts new file mode 100644 index 000000000..ee7af364b --- /dev/null +++ b/apps/api/src/billing/services/anonymous-validate/anonymous-validate.ts @@ -0,0 +1,36 @@ +import * as v1beta4 from "@akashnetwork/akash-api/v1beta4"; +import { EncodeObject } from "@cosmjs/proto-signing"; +import { singleton } from "tsyringe"; + +import { UserWalletOutput } from "@src/billing/repositories"; +import { ChainErrorService } from "../chain-error/chain-error.service"; + +@singleton() +export class AnonymousValidateService { + private readonly authorizedProviders = [ + "akash1824w2vqx57n8zr8707dnyh85kjrkfkrrs94pk9", + "akash19ah5c95kq4kz2g6q5rdkdgt80kc3xycsd8plq8", + "akash1g7az2pus6atgeufgttlcnl0wzlzwd0lrsy6d7s", + "akash1tfuvntkwt3cpxnhukdnsvvsumjnrvmvh244l3w", + "akash18mcffkg5jp9eqc36evlv67uqcj04fvk324ap54", + "akash1t0sk5nhc8n3xply5ft60x9det0s7jwplzzycnv", + "akash1cnzkdynwd4u6j7s8z5j0fg76h3g6yhsggmuqta", + "akash1eyrkgz2ufjs27hnpe3jekemp8anrfk8tqzhpsn", + "akash15tl6v6gd0nte0syyxnv57zmmspgju4c3xfmdhk", + "akash1rfqs6aajq2d4azhjj88wav2d6ra6vvuzn58dt5", + "akash16aflfteeg8c2j63sy0rlxj57pty98zzm5mvgfa" + ]; + + constructor(private readonly chainErrorService: ChainErrorService) {} + + validateLeaseProviders(decoded: EncodeObject, userWallet: UserWalletOutput) { + if (userWallet.isTrialing && decoded.typeUrl === "/akash.market.v1beta4.MsgCreateLease") { + const value = decoded.value as v1beta4.MsgCreateLease; + if (!this.authorizedProviders.includes(value.bidId.provider)) { + throw new Error(`provider not authorized: ${value.bidId.provider}`); + } + } + + return true; + } +} diff --git a/apps/api/src/billing/services/chain-error/chain-error.service.ts b/apps/api/src/billing/services/chain-error/chain-error.service.ts index 8dabc0574..51d564e6e 100644 --- a/apps/api/src/billing/services/chain-error/chain-error.service.ts +++ b/apps/api/src/billing/services/chain-error/chain-error.service.ts @@ -8,11 +8,16 @@ export class ChainErrorService { "insufficient funds": { code: 400, message: "Insufficient funds" + }, + "provider not authorized": { + code: 400, + message: "Provider not authorized" } }; private MESSAGE_ERROR_TITLES: Record = { - "/akash.deployment.v1beta3.MsgCreateDeployment": "Failed to create deployment" + "/akash.deployment.v1beta3.MsgCreateDeployment": "Failed to create deployment", + "/akash.market.v1beta4.MsgCreateLease": "Failed to create lease" }; public toAppError(error: Error, messages: readonly EncodeObject[]) { diff --git a/apps/api/src/billing/services/tx-signer/tx-signer.service.ts b/apps/api/src/billing/services/tx-signer/tx-signer.service.ts index a4a316d92..02699ba49 100644 --- a/apps/api/src/billing/services/tx-signer/tx-signer.service.ts +++ b/apps/api/src/billing/services/tx-signer/tx-signer.service.ts @@ -12,6 +12,7 @@ import { InjectTypeRegistry } from "@src/billing/providers/type-registry.provide import { UserWalletOutput, UserWalletRepository } from "@src/billing/repositories"; import { MasterWalletService } from "@src/billing/services"; import { BalancesService } from "@src/billing/services/balances/balances.service"; +import { AnonymousValidateService } from "../anonymous-validate/anonymous-validate"; import { ChainErrorService } from "../chain-error/chain-error.service"; type StringifiedEncodeObject = Omit & { value: string }; @@ -32,7 +33,8 @@ export class TxSignerService { private readonly masterWalletService: MasterWalletService, private readonly balancesService: BalancesService, private readonly authService: AuthService, - private readonly chainErrorService: ChainErrorService + private readonly chainErrorService: ChainErrorService, + private readonly anonymousValidateService: AnonymousValidateService ) {} async signAndBroadcast(userId: UserWalletOutput["userId"], messages: StringifiedEncodeObject[]) { @@ -41,6 +43,12 @@ export class TxSignerService { const decodedMessages = this.decodeMessages(messages); + try { + decodedMessages.forEach(message => this.anonymousValidateService.validateLeaseProviders(message, userWallet)); + } catch (error) { + throw this.chainErrorService.toAppError(error, decodedMessages); + } + const client = await this.getClientForAddressIndex(userWallet.id); const tx = await client.signAndBroadcast(decodedMessages); diff --git a/apps/deploy-web/src/components/new-deployment/CreateLease.tsx b/apps/deploy-web/src/components/new-deployment/CreateLease.tsx index 9ff0c9199..0bab8de19 100644 --- a/apps/deploy-web/src/components/new-deployment/CreateLease.tsx +++ b/apps/deploy-web/src/components/new-deployment/CreateLease.tsx @@ -203,6 +203,8 @@ export const CreateLease: React.FunctionComponent = ({ dseq }) => { label: "Create lease" }); await sendManifest(); + } catch (error) { + console.error(error); } finally { setIsCreatingLeases(false); } diff --git a/package-lock.json b/package-lock.json index 9b3d25115..453bf5ab9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ }, "apps/api": { "name": "@akashnetwork/console-api", - "version": "2.24.0", + "version": "2.25.0", "license": "Apache-2.0", "dependencies": { "@akashnetwork/akash-api": "^1.3.0", @@ -270,7 +270,7 @@ }, "apps/deploy-web": { "name": "@akashnetwork/console-web", - "version": "2.17.0", + "version": "2.19.1-beta.0", "license": "Apache-2.0", "dependencies": { "@akashnetwork/akash-api": "^1.3.0",