diff --git a/deploy-web/package-lock.json b/deploy-web/package-lock.json index 415b2c479..ef8f0697a 100644 --- a/deploy-web/package-lock.json +++ b/deploy-web/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@akashnetwork/akash-api": "^1.3.0", - "@akashnetwork/akashjs": "^0.9.0", + "@akashnetwork/akashjs": "^0.10.0", "@auth0/nextjs-auth0": "^3.5.0", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", @@ -159,9 +159,9 @@ "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==" }, "node_modules/@akashnetwork/akash-api": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@akashnetwork/akash-api/-/akash-api-1.3.0.tgz", - "integrity": "sha512-sZSMg4KsL6vpPs+c6ejcYqyKehTrfasrYEa9Leg/iPPcllSqaFI9EfiP+UQs0Ku2PpMWAZ1Z+c/Pnfr823AEKw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@akashnetwork/akash-api/-/akash-api-1.4.0.tgz", + "integrity": "sha512-xJTHjkSLHQRk2z1s+pk/fSTXQrJCTyzUzWHn+TvvJapjEsDPT0+AW2YhrmYLOpS0n4s/8GnoGB9swRuzgYYLbg==", "dependencies": { "rxjs": "^7.8.1" }, @@ -178,11 +178,11 @@ } }, "node_modules/@akashnetwork/akashjs": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@akashnetwork/akashjs/-/akashjs-0.9.1.tgz", - "integrity": "sha512-zgm56eF9ADZmOp5MIET5JOhfR5edKAD2K7wcYXnzlxD8jGTJPZMwn9TisPXTz6INVQjr0b2tvU49KnG64pv4fg==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@akashnetwork/akashjs/-/akashjs-0.10.0.tgz", + "integrity": "sha512-hTNoYhTutDPFd2QuQ7FaRxsv2crOIYU1NxIDyvXoVyHs6/27R4NWu5OdoDkGQqz5vQezUxexf4JG67X67IFw6A==", "dependencies": { - "@akashnetwork/akash-api": "^1.3.0", + "@akashnetwork/akash-api": "^1.4.0", "@cosmjs/launchpad": "^0.27.0", "@cosmjs/proto-signing": "^0.28.11", "@cosmjs/stargate": "^0.28.0", diff --git a/deploy-web/package.json b/deploy-web/package.json index 9e856c071..3f9581cfa 100644 --- a/deploy-web/package.json +++ b/deploy-web/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "@akashnetwork/akash-api": "^1.3.0", - "@akashnetwork/akashjs": "^0.9.0", + "@akashnetwork/akashjs": "^0.10.0", "@auth0/nextjs-auth0": "^3.5.0", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", diff --git a/deploy-web/src/components/deployments/ManifestUpdate.tsx b/deploy-web/src/components/deployments/ManifestUpdate.tsx index d944a824f..51235b79f 100644 --- a/deploy-web/src/components/deployments/ManifestUpdate.tsx +++ b/deploy-web/src/components/deployments/ManifestUpdate.tsx @@ -36,7 +36,7 @@ type Props = { export const ManifestUpdate: React.FunctionComponent = ({ deployment, leases, closeManifestEditor }) => { const [parsingError, setParsingError] = useState(null); - const [deploymentVersion, setDeploymentVersion] = useState(null); + const [deploymentVersion, setDeploymentVersion] = useState(null); const [editedManifest, setEditedManifest] = useState(""); const [isSendingManifest, setIsSendingManifest] = useState(false); const [showOutsideDeploymentMessage, setShowOutsideDeploymentMessage] = useState(false); @@ -54,7 +54,7 @@ export const ManifestUpdate: React.FunctionComponent = ({ deployment, lea setEditedManifest(localDeploymentData?.manifest); const yamlVersion = yaml.load(localDeploymentData?.manifest); - const version = await deploymentData.getManifestVersion(yamlVersion, true); + const version = await deploymentData.getManifestVersion(yamlVersion); setDeploymentVersion(version); } else { @@ -113,9 +113,7 @@ export const ManifestUpdate: React.FunctionComponent = ({ deployment, lea async function sendManifest(providerInfo: ApiProviderList, manifest: any) { try { - const response = await sendManifestToProvider(providerInfo, manifest, deployment.dseq, localCert as LocalCert); - - return response; + return await sendManifestToProvider(providerInfo, manifest, deployment.dseq, localCert as LocalCert); } catch (err) { enqueueSnackbar(, { variant: "error", autoHideDuration: null }); throw err; diff --git a/deploy-web/src/utils/deploymentData/v1beta3.ts b/deploy-web/src/utils/deploymentData/v1beta3.ts index 9fb0c03f3..5112d89d1 100644 --- a/deploy-web/src/utils/deploymentData/v1beta3.ts +++ b/deploy-web/src/utils/deploymentData/v1beta3.ts @@ -1,144 +1,20 @@ -import { CustomValidationError, DeploymentGroups, getCurrentHeight, getSdl, Manifest, ManifestVersion, parseSizeStr } from "./helpers"; -import { defaultInitialDeposit } from "../constants"; -import { stringToBoolean } from "../stringUtils"; -import path from "path"; -import yaml from "js-yaml"; import { getSelectedNetwork } from "@src/hooks/useSelectedNetwork"; -import { NetworkId } from "@akashnetwork/akashjs/build/types/network"; - -export const endpointNameValidationRegex = /^[a-z]+[-_\da-z]+$/; - -function validate(yamlStr: string, yamlJson, networkId: NetworkId) { - try { - // TODO: use result of this in client code instead of just using validation - getSdl(yamlJson, "beta3", networkId); - } catch (e) { - const error = new CustomValidationError(e.message); - error.stack = e.stack; - throw error; - } - - Object.keys(yamlJson.services).forEach(svcName => { - const svc = yamlJson.services[svcName]; - const depl = yamlJson.deployment[svcName]; - - Object.keys(depl).forEach(placementName => { - const svcdepl = depl[placementName]; - const compute = yamlJson.profiles.compute[svcdepl.profile]; - - // STORAGE VALIDATION - const storages = compute.resources.storage.map ? compute.resources.storage : [compute.resources.storage]; - const volumes = {}; - const attr = {}; - const mounts = {}; - - storages?.forEach(storage => { - const name = storage.name || "default"; - volumes[name] = { - name, - quantity: { val: parseSizeStr(storage.size) }, - attributes: - storage.attributes && - Object.keys(storage.attributes) - .sort() - .map(key => { - const value = storage.attributes[key].toString(); - // add the storage attributes - attr[key] = value; - - return { - key, - value - }; - }) - }; - }); - - if (svc.params) { - (Object.keys(svc.params?.storage || {}) || []).forEach(name => { - const params = svc.params.storage[name]; - if (!volumes[name]) { - throw new CustomValidationError(`Service "${svcName}" references to no-existing compute volume names "${name}".`); - } - - if (!path.isAbsolute(params.mount)) { - throw new CustomValidationError(`Invalid value for "service.${svcName}.params.${name}.mount" parameter. expected absolute path.`); - } - - // merge the service params attributes - attr["mount"] = params.mount; - attr["readOnly"] = params.readOnly || false; - const mount = attr["mount"]; - const vlname = mounts[mount]; - - if (vlname) { - if (!mount) { - throw new CustomValidationError("Multiple root ephemeral storages are not allowed"); - } - - throw new CustomValidationError(`Mount ${mount} already in use by volume ${vlname}.`); - } - - mounts[mount] = name; - }); - } - (Object.keys(volumes) || []).forEach(volume => { - volumes[volume].attributes?.forEach(nd => { - attr[nd.key] = nd.value; - }); - - const persistent = stringToBoolean(attr["persistent"]); - - if (persistent && !attr["mount"]) { - throw new CustomValidationError( - `compute.storage.${volume} has persistent=true which requires service.${svcName}.params.storage.${volume} to have mount.` - ); - } - }); - - // GPU VALIDATION - const gpu = compute.resources.gpu; - - if (gpu) { - if (gpu.units === 0 && gpu.attributes) { - throw new CustomValidationError(`Invalid GPU configuration for "${svcName}".`); - } - - if (gpu.units > 0 && !gpu.attributes) { - throw new CustomValidationError(`Invalid GPU configuration for "${svcName}". Missing attributes with vendor and nvidia.`); - } - - if (gpu.units > 0 && !("vendor" in gpu.attributes)) { - throw new CustomValidationError(`Invalid GPU configuration for "${svcName}". Missing vendor with nvidia in attributes.`); - } - - if (gpu.units > 0 && !("nvidia" in gpu.attributes.vendor)) { - throw new CustomValidationError(`Invalid GPU configuration for "${svcName}". Missing nvidia in attributes.vendor.`); - } +import { CustomValidationError, getCurrentHeight, getSdl, Manifest, ManifestVersion, parseSizeStr } from "./helpers"; +import { defaultInitialDeposit } from "../constants"; - if (gpu.units > 0 && !!gpu.attributes.vendor.nvidia && !Array.isArray(gpu.attributes.vendor.nvidia)) { - throw new CustomValidationError(`Invalid GPU configuration for "${svcName}". Nvidia must be an array of GPU models with optional ram.`); - } - } - }); - }); -} +export const endpointNameValidationRegex = /^[a-z]+[-_\da-z]+$/; export function getManifest(yamlJson, asString: boolean) { const network = getSelectedNetwork(); return Manifest(yamlJson, "beta3", network.id, asString); } -export async function getManifestVersion(yamlJson, asString = false) { +export async function getManifestVersion(yamlJson) { const network = getSelectedNetwork(); const version = await ManifestVersion(yamlJson, "beta3", network.id); - if (asString) { - return Buffer.from(version).toString("base64"); - } else { - return version; - } + return Buffer.from(version).toString("base64"); } const getDenomFromSdl = (groups: any[]): string => { @@ -151,43 +27,40 @@ const getDenomFromSdl = (groups: any[]): string => { export async function NewDeploymentData( apiEndpoint: string, yamlStr: string, - dseq: string, + dseq: string | null, fromAddress: string, deposit = defaultInitialDeposit, - depositorAddress = null + depositorAddress: string | null = null ) { - const { id: networkId } = getSelectedNetwork(); - const yamlJson = yaml.load(yamlStr) as any; - - // Validate the integrity of the yaml - validate(yamlStr, yamlJson, networkId); - - const groups = DeploymentGroups(yamlJson, "beta3", networkId); - const mani = Manifest(yamlJson, "beta3", networkId); - const denom = getDenomFromSdl(groups); - const version = await ManifestVersion(yamlJson, "beta3", networkId); - const id = { - owner: fromAddress, - dseq: dseq - }; - const _deposit = { - denom, - amount: deposit.toString() - }; - - if (!id.dseq) { - id.dseq = (await getCurrentHeight(apiEndpoint)).toString(); + try { + const { id: networkId } = getSelectedNetwork(); + const sdl = getSdl(yamlStr, "beta3", networkId); + const groups = sdl.groups(); + const mani = sdl.manifest(); + const denom = getDenomFromSdl(groups); + const version = await sdl.manifestVersion(); + const _deposit = { + denom, + amount: deposit.toString() + }; + + return { + sdl: sdl.data, + manifest: mani, + groups: groups, + deploymentId: { + owner: fromAddress, + dseq: dseq || (await getCurrentHeight(apiEndpoint)).toString() + }, + orderId: [], + leaseId: [], + version, + deposit: _deposit, + depositor: depositorAddress || fromAddress + }; + } catch (e) { + const error = new CustomValidationError(e.message); + error.stack = e.stack; + throw error; } - - return { - sdl: yamlJson, - manifest: mani, - groups: groups, - deploymentId: id, - orderId: [], - leaseId: [], - version, - deposit: _deposit, - depositor: depositorAddress || fromAddress - }; } diff --git a/deploy-web/src/utils/deploymentLocalDataUtils.ts b/deploy-web/src/utils/deploymentLocalDataUtils.ts index a9d305996..760435c52 100644 --- a/deploy-web/src/utils/deploymentLocalDataUtils.ts +++ b/deploy-web/src/utils/deploymentLocalDataUtils.ts @@ -7,18 +7,15 @@ export type LocalDeploymentData = { manifestVersion?: Uint8Array; }; -export function getDeploymentLocalData(dseq: string | number) { +export function getDeploymentLocalData(dseq: string | number): LocalDeploymentData | null { 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; - const parsedData = JSON.parse(dataStr) as LocalDeploymentData; - - return parsedData; + return dataStr ? JSON.parse(dataStr) : null; } export function saveDeploymentManifestAndName(dseq: string, manifest: string, version: Uint8Array, address: string, name: string) { diff --git a/deploy-web/src/utils/init.ts b/deploy-web/src/utils/init.ts index 0245671db..a3e6e0903 100644 --- a/deploy-web/src/utils/init.ts +++ b/deploy-web/src/utils/init.ts @@ -1,5 +1,4 @@ import { setNetworkVersion } from "./constants"; -import { initDeploymentData } from "./deploymentData"; import { initProtoTypes } from "./proto"; import { setMessageTypes } from "./TransactionMessageData"; @@ -7,5 +6,4 @@ export const initAppTypes = () => { setNetworkVersion(); initProtoTypes(); setMessageTypes(); - initDeploymentData(); };