From b75b31d41f156acef53324d106c42dc6ae517998 Mon Sep 17 00:00:00 2001 From: Joseph Tary Date: Thu, 27 Jul 2023 19:07:02 -0700 Subject: [PATCH 1/4] fix: button styling on deployment page --- .../Deployment/DeploymentActionButton.tsx | 32 ++-- web/src/components/Deployment/index.tsx | 169 +++++++++--------- 2 files changed, 100 insertions(+), 101 deletions(-) diff --git a/web/src/components/Deployment/DeploymentActionButton.tsx b/web/src/components/Deployment/DeploymentActionButton.tsx index 11a2b20..6c9c3b8 100644 --- a/web/src/components/Deployment/DeploymentActionButton.tsx +++ b/web/src/components/Deployment/DeploymentActionButton.tsx @@ -2,29 +2,29 @@ import React from 'react'; import { Button, Stack, Link, Tooltip, ButtonProps } from '@mui/material'; type DeploymentActionButtonProps = { - tooltipTitle: string; - tooltip: React.ReactNode; - linkTo: string; - children: React.ReactNode; + tooltipTitle: string; + tooltip: React.ReactNode; + linkTo: string; + children: React.ReactNode; } & ButtonProps; -const ConditionalTooltip = ({ children, condition, ...rest}: any) => { - return condition - ? {children} - : {children}; +const ConditionalTooltip = ({ children, condition, ...rest }: any) => { + return condition + ? {children} + : {children}; }; const DeploymentActionButton: React.FC = (props) => { - const { - tooltipTitle, - tooltip, - linkTo, - children, - ...rest - } = props; + const { + tooltipTitle, + tooltip, + linkTo, + children, + ...rest + } = props; - return + return = () => { ) : null} -
Actions
- {deployment?.deployment && deploymentIncomplete && ( - - )} - {deployment?.deployment && !deploymentIncomplete && ( - - } - > - Update Deployment - - - +
Actions
+ {deployment?.deployment && deploymentIncomplete && ( + + )} + {deployment?.deployment && !deploymentIncomplete && ( + + } + > + Update Deployment + - - } > - - - {ReDeployTooltip} - - } + > + Re-Deploy + + + {ReDeployTooltip} +
+ + Clone Deployment + + + )} + {deployment?.deployment && deployment?.deployment?.state === 1 && ( + setRefresh(true)} > - Clone Deployment - - - )} - {deployment?.deployment && deployment?.deployment?.state === 1 && ( - setRefresh(true)} - > - Delete Deployment - - )} + Delete Deployment + + )} +
Info
From c4785d408d767af9ad0f22a0852e833c1a5b5cbc Mon Sep 17 00:00:00 2001 From: Joseph Tary Date: Wed, 2 Aug 2023 13:59:41 -0700 Subject: [PATCH 2/4] fix: add missing headers for persistant storage --- web/.eslintrc.yml | 1 + web/src/_helpers/async-for-each.ts | 13 --- web/src/api/rpc/beta2/deployments.tsx | 49 ++++----- web/src/api/rpc/beta3/deployments.tsx | 44 ++++---- .../MeasurementControl/InputNumbers.tsx | 2 +- web/src/components/SdlConfiguration/Gpu.tsx | 28 ++++- web/src/components/SdlConfiguration/Ports.tsx | 24 +--- .../components/SdlConfiguration/Storage.tsx | 43 +++++--- .../components/SdlConfiguration/styling.tsx | 9 +- web/src/hooks/useDeploymentData.ts | 104 +++++++++--------- 10 files changed, 159 insertions(+), 158 deletions(-) delete mode 100644 web/src/_helpers/async-for-each.ts diff --git a/web/.eslintrc.yml b/web/.eslintrc.yml index 90c50f2..d5a5b21 100644 --- a/web/.eslintrc.yml +++ b/web/.eslintrc.yml @@ -26,5 +26,6 @@ rules: semi: - error - always + @typescript-eslint/no-explicit-any: "off" react/react-in-jsx-scope: "off" react/no-unescaped-entities: "off" diff --git a/web/src/_helpers/async-for-each.ts b/web/src/_helpers/async-for-each.ts deleted file mode 100644 index e67e35f..0000000 --- a/web/src/_helpers/async-for-each.ts +++ /dev/null @@ -1,13 +0,0 @@ -type asyncFn = (elem: T, index: number, array: T[]) => Promise; - -function noop(result: T) { - return result; -} - -export async function asyncForEach(arr: Array, callback: asyncFn) { - return asyncMap(arr, callback).then(noop); -} - -export async function asyncMap(arr: Array, callback: asyncFn) { - return Promise.all(arr.map(callback)); -} diff --git a/web/src/api/rpc/beta2/deployments.tsx b/web/src/api/rpc/beta2/deployments.tsx index 71a03bd..b632e8b 100644 --- a/web/src/api/rpc/beta2/deployments.tsx +++ b/web/src/api/rpc/beta2/deployments.tsx @@ -41,11 +41,12 @@ import { fetchRpcNodeStatus } from './rpc'; import { LeaseStatus } from '../../../types'; import logging from '../../../logging'; import { getRpcNode } from '../../../hooks/useRpcNode'; +import { retry } from '../../../_helpers/async-utils'; // 5AKT aka 5000000uakt export const defaultInitialDeposit = 5000000; -function getTypeUrl(type: T) { +function getTypeUrl(type: T) { return `/${type.$type}`; } @@ -399,8 +400,6 @@ export async function sendManifest(address: string, lease: Lease, sdl: any) { const providerFetch = mtlsFetch(cert, provider.provider.hostUri); const manifest = Manifest(sdl, 'beta2', true); - console.log(manifest); - let jsonStr = JSON.stringify(manifest); jsonStr = jsonStr.replaceAll('"quantity":{"val', '"size":{"val'); @@ -408,32 +407,24 @@ export async function sendManifest(address: string, lease: Lease, sdl: any) { jsonStr = jsonStr.replaceAll('"readOnly":', '"mount":'); jsonStr = jsonStr.replaceAll('"readOnlyTmp":', '"readOnly":'); - return new Promise((resolve, reject) => { - const attemptSend = (retry: number) => { - return providerFetch(url, { - method: 'PUT', - body: jsonStr, - }).then((result) => { - if (result.ok) { - resolve(result); - return; - } - - if (retry > 0) { - // logging.warn('Sending manifest failed. Retrying...'); - setTimeout(() => attemptSend(retry - 1), 1000); - } else { - // logging.warn('Sending manifest failed.'); - result.text().then(reject); - } - }, (error) => { - logging.error('Error sending manifest to provider. This is likey an issue with the provider.'); - console.error(error); - }); - }; - - attemptSend(3); - }); + const attemptSend = () => { + return providerFetch(url, { + method: 'PUT', + body: jsonStr, + }).then((result) => { + if (result.ok) { + return result; + } + + return Promise.reject(result); + }); + }; + + return retry(attemptSend, [1000, 3000, 5000]) + .catch((error) => { + logging.error('Error sending manifest to provider. This is likely an issue with the provider.'); + console.error(error); + }); } export async function newDeploymentData( diff --git a/web/src/api/rpc/beta3/deployments.tsx b/web/src/api/rpc/beta3/deployments.tsx index e11beba..1aea238 100644 --- a/web/src/api/rpc/beta3/deployments.tsx +++ b/web/src/api/rpc/beta3/deployments.tsx @@ -41,11 +41,12 @@ import { fetchRpcNodeStatus } from './rpc'; import { LeaseStatus } from '../../../types'; import logging from '../../../logging'; import { getRpcNode } from '../../../hooks/useRpcNode'; +import { retry } from '../../../_helpers/async-utils'; // 5AKT aka 5000000uakt export const defaultInitialDeposit = 5000000; -function getTypeUrl(type: T) { +function getTypeUrl(type: T) { return `/${type.$type}`; } @@ -400,29 +401,24 @@ export async function sendManifest(address: string, lease: Lease, sdl: any) { const providerFetch = mtlsFetch(cert, provider.provider.hostUri); const jsonStr = ManifestYaml(sdl, 'beta3'); - return new Promise((resolve, reject) => { - const attemptSend = (retry: number) => { - return providerFetch(url, { - method: 'PUT', - body: jsonStr, - }).then((result) => { - if (result.ok) { - resolve(result); - return; - } - - if (retry > 0) { - // logging.warn('Sending manifest failed. Retrying...'); - setTimeout(() => attemptSend(retry - 1), 1000); - } else { - // logging.warn('Sending manifest failed.'); - result.text().then(reject); - } - }); - }; - - attemptSend(3); - }); + const attemptSend = () => { + return providerFetch(url, { + method: 'PUT', + body: jsonStr, + }).then((result) => { + if (result.ok) { + return result; + } + + return Promise.reject(result); + }); + }; + + return retry(attemptSend, [1000, 3000, 5000]) + .catch((error: any) => { + logging.error('Error sending manifest to provider. This is likely an issue with the provider.'); + console.error(error); + }); } export async function newDeploymentData( diff --git a/web/src/components/MeasurementControl/InputNumbers.tsx b/web/src/components/MeasurementControl/InputNumbers.tsx index 65083ef..7c206af 100644 --- a/web/src/components/MeasurementControl/InputNumbers.tsx +++ b/web/src/components/MeasurementControl/InputNumbers.tsx @@ -33,7 +33,7 @@ export const InputNumber: React.FC = ({ setFieldValue, disable { diff --git a/web/src/components/SdlConfiguration/Gpu.tsx b/web/src/components/SdlConfiguration/Gpu.tsx index 67e2f2a..a942fa0 100644 --- a/web/src/components/SdlConfiguration/Gpu.tsx +++ b/web/src/components/SdlConfiguration/Gpu.tsx @@ -5,6 +5,28 @@ import { AddNewButton, AddNewButtonWrapper, FieldWrapper, PlusSign, SdlSectionWr import { Button, Box, Stack, Typography, List, ListItem, OutlinedInput } from '@mui/material'; import { IconTrash } from '../Icons'; +const GPU_VENDORS = [ + 'nvidia', + 'amd', +]; + +const GPU_MODELS = { + nvidia: [ + 'a100', + 'a30', + 'a40', + 'a6000', + 'a40', + ], + amd: [ + 'mi100', + 'mi50', + 'mi60', + 'mi25', + 'mi8', + ] +}; + type GpuUnitProps = { currentProfile: string; disabled: boolean; @@ -81,11 +103,7 @@ const GpuAttributes: React.FC = ({ currentProfile, disabled }) => return ( - Example filters: - - /vendor/nvidia/model/a6000 (nVidia A6000 only) - /vendor/amd/model/* (any AMD GPU) - + Select the GPU vendors/models that you'd like to use for your deployment. {attributes.map((attribute, index) => ( diff --git a/web/src/components/SdlConfiguration/Ports.tsx b/web/src/components/SdlConfiguration/Ports.tsx index 8a04d91..d545a46 100644 --- a/web/src/components/SdlConfiguration/Ports.tsx +++ b/web/src/components/SdlConfiguration/Ports.tsx @@ -11,6 +11,7 @@ import { FieldWrapper, Input, SdlSectionWrapper, + TableTitle, VariableWrapper, } from './styling'; @@ -46,10 +47,10 @@ export const Ports: React.FC = ({ serviceName, services, updatePage render={(arrayHelpers: any) => ( - Port - As - Host - Accept + Port + As + Host + Accept {services[serviceName]?.expose?.map((port, index) => ( @@ -173,17 +174,4 @@ export const Ports: React.FC = ({ serviceName, services, updatePage const HostFiledWithButton = styled.div` display: flex; column-gap: 10px; -`; - -const PortTitle = styled.div` - font-weight: 500; - font-size: 14px; - color: #3d4148; - padding-right: 10px; - width: 176.5px; - box-sizing: border-box; - - &:last-child { - width: auto; - } -`; +`; \ No newline at end of file diff --git a/web/src/components/SdlConfiguration/Storage.tsx b/web/src/components/SdlConfiguration/Storage.tsx index c2e57db..489f63b 100644 --- a/web/src/components/SdlConfiguration/Storage.tsx +++ b/web/src/components/SdlConfiguration/Storage.tsx @@ -1,4 +1,4 @@ -import { FormControl, IconButton, MenuItem, Select, Tab, Tabs, Tooltip } from '@mui/material'; +import { Box, FormControl, IconButton, MenuItem, Select, Stack, Tab, Tabs, Tooltip } from '@mui/material'; import { Field, FieldArray } from 'formik'; import { MeasurementControl } from '../MeasurementControl'; import React from 'react'; @@ -13,6 +13,7 @@ import { VariableWrapper, TrashIcon, PlusSign, + TableTitle, } from './styling'; interface TabPanelProps { @@ -21,21 +22,19 @@ interface TabPanelProps { value: number; } -const validateStorage = (value: any) => { - let error; - const strippedValue = value?.slice(0, -2); - if (strippedValue && strippedValue <= 0) { - error = 'Storage must be a positive value greater than zero'; +const validateStorage = (value: string) => { + const size = value.slice(0, -2); + const intValue = parseInt(size, 10); + + if (isNaN(intValue) || intValue <= 0) { + return 'Storage must be a positive value greater than zero'; } - return error; }; -const validateStorageData = (value: any) => { - let error; - if (!value) { - error = 'This value can\'t be blank'; +const validateStorageData = (value: string) => { + if (value === '') { + return 'This value can\'t be blank'; } - return error; }; type StorageProfile = { @@ -78,7 +77,7 @@ export const Storage: React.FC = ({ sx={{ marginBottom: '16px', borderBottom: '1px solid #D1D5DB' }} > - + = ({ /> + {/* Persistent storage */} + + Name + Mount + Size + Type + ( @@ -180,7 +186,14 @@ export const Storage: React.FC = ({ {profiles.compute[currentProfile]?.resources.storage?.map((storage, index) => { return ( storage?.attributes && ( - + = ({ )} - + ) ); })} diff --git a/web/src/components/SdlConfiguration/styling.tsx b/web/src/components/SdlConfiguration/styling.tsx index b9630fd..e82e684 100644 --- a/web/src/components/SdlConfiguration/styling.tsx +++ b/web/src/components/SdlConfiguration/styling.tsx @@ -1,6 +1,6 @@ import styled from '@emotion/styled'; import { css } from '@emotion/react'; -import { Button } from '@mui/material'; +import { Box, Button } from '@mui/material'; import PlusIcon from '../../assets/images/plus-icon.svg'; import Trash from '../../assets/images/icon-trash.svg'; @@ -102,3 +102,10 @@ export const SdlSectionWrapper = styled.div` border-radius: 6px; padding: 20px; `; + +export const TableTitle = styled(Box)` + font-weight: 500; + font-size: 14px; + color: #3d4148; + box-sizing: border-box; +`; diff --git a/web/src/hooks/useDeploymentData.ts b/web/src/hooks/useDeploymentData.ts index 2e18746..549dbb2 100644 --- a/web/src/hooks/useDeploymentData.ts +++ b/web/src/hooks/useDeploymentData.ts @@ -63,7 +63,6 @@ export default function useDeploymentData(owner: string) { const getLeaseStatus = useCallback( (lease: any) => { if (certificate.$type === 'TLS Certificate') { - // console.log('fetching status for lease', lease); return lease && fetchLeaseStatus(lease, rpcEndpoint); } }, @@ -86,57 +85,58 @@ export default function useDeploymentData(owner: string) { // Map it all together, and your mother's brother is named Robert Promise.all( - deploymentsQuery.deployments.map(async (query) => { - let name = ''; - let url = ''; - const lease = getDeploymentLease(query.deployment); - const status = await getLeaseStatus(lease); - const leaseInfo = leaseCalculator( - query?.deployment as any, - query?.escrowAccount as any, - lease as any, - akt?.current_price || 0 - ); - let updatable = 0; - // Doing this cause dseq sometimes comes as plain object and not Long type, - // and if that happen can't crate dseq string - const dseq = new Long( - query.deployment?.deploymentId?.dseq?.low || 0, - query.deployment?.deploymentId?.dseq?.high, - query.deployment?.deploymentId?.dseq?.unsigned - )?.toString(); - - const appCache = dseq ? localStorage.getItem(dseq) : null; - - const application = appCache ? JSON.parse(appCache) : null; - - if (application !== null && application.name !== '') { - name = application.name; - } else { - name = uniqueName(keplr?.accounts[0]?.address, dseq); - } - if (status && status.services) { - url = Object.values(status.services) - .map((service) => (service as any).uris[0]) - .join(', '); - } - if (application !== null && query.deployment?.state === 1 && application.sdl !== undefined) { - updatable = 1; - } else { - updatable = 0; - } - // Table row object - return { - name, - dseq, - url, - lease: leaseInfo - ? `Time Left: ${leaseInfo ? leaseInfo.timeLeft : 'N/A'}` - : 'Time Left: 0 days', - status: query.deployment?.state || 0, - updatable: updatable, - }; - }) + deploymentsQuery.deployments + .map(async (query) => { + let name = ''; + let url = ''; + const lease = getDeploymentLease(query.deployment); + const status = await getLeaseStatus(lease); + const leaseInfo = leaseCalculator( + query?.deployment as any, + query?.escrowAccount as any, + lease as any, + akt?.current_price || 0 + ); + let updatable = 0; + // Doing this cause dseq sometimes comes as plain object and not Long type, + // and if that happen can't crate dseq string + const dseq = new Long( + query.deployment?.deploymentId?.dseq?.low || 0, + query.deployment?.deploymentId?.dseq?.high, + query.deployment?.deploymentId?.dseq?.unsigned + )?.toString(); + + const appCache = dseq ? localStorage.getItem(dseq) : null; + + const application = appCache ? JSON.parse(appCache) : null; + + if (application !== null && application.name !== '') { + name = application.name; + } else { + name = uniqueName(keplr?.accounts[0]?.address, dseq); + } + if (status && status.services) { + url = Object.values(status.services) + .map((service) => (service as any).uris[0]) + .join(', '); + } + if (application !== null && query.deployment?.state === 1 && application.sdl !== undefined) { + updatable = 1; + } else { + updatable = 0; + } + // Table row object + return { + name, + dseq, + url, + lease: leaseInfo + ? `Time Left: ${leaseInfo ? leaseInfo.timeLeft : 'N/A'}` + : 'Time Left: 0 days', + status: query.deployment?.state || 0, + updatable: updatable, + }; + }) ).then(setDeploymentsData); }, [status, deploymentsQuery, getDeploymentLease, getLeaseStatus]); From f8881d2fc5c5789e4ea266a45d256efe5d132e3a Mon Sep 17 00:00:00 2001 From: Joseph Tary Date: Wed, 2 Aug 2023 15:50:44 -0700 Subject: [PATCH 3/4] fix: auto-initialize storage for services --- web/src/components/SdlConfiguration/Storage.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/src/components/SdlConfiguration/Storage.tsx b/web/src/components/SdlConfiguration/Storage.tsx index 489f63b..2063557 100644 --- a/web/src/components/SdlConfiguration/Storage.tsx +++ b/web/src/components/SdlConfiguration/Storage.tsx @@ -306,6 +306,14 @@ export const Storage: React.FC = ({ variant="outlined" size="small" onClick={() => { + const sdl = arrayHelpers.form.values.sdl as SDLSpec; + + if (sdl.services[serviceName]?.params?.storage === undefined) { + sdl.services[serviceName].params = { + storage: {}, + }; + } + arrayHelpers.insert( profiles.compute[currentProfile]?.resources.storage?.length + 1 ?? 0, { From 6443f8461bd0a6710426e50e2078268a63da0b05 Mon Sep 17 00:00:00 2001 From: Joseph Tary Date: Wed, 30 Aug 2023 16:33:00 -0700 Subject: [PATCH 4/4] feat: updates to support sandbox --- web/.eslintrc.yml | 2 +- web/package.json | 4 +- web/src/_helpers/async-utils.ts | 66 ++++++++++ web/src/_helpers/sandbox-chain.ts | 41 ++++++ .../_helpers/{chain.ts => testnet-chain.ts} | 0 web/src/api/rpc/beta3/deployments.tsx | 2 + .../Deployment/DeploymentActionButton.tsx | 3 + web/src/components/Deployment/index.tsx | 19 +-- .../components/DeploymentStepper/index.tsx | 124 ++++++++---------- .../SdlConfiguration/HttpOptions.tsx | 2 +- .../components/SdlConfiguration/Storage.tsx | 3 +- web/src/hooks/useRpcNode.ts | 5 + web/src/pages/Settings.tsx | 30 +++-- yarn.lock | 8 +- 14 files changed, 210 insertions(+), 99 deletions(-) create mode 100644 web/src/_helpers/async-utils.ts create mode 100644 web/src/_helpers/sandbox-chain.ts rename web/src/_helpers/{chain.ts => testnet-chain.ts} (100%) diff --git a/web/.eslintrc.yml b/web/.eslintrc.yml index d5a5b21..0906aff 100644 --- a/web/.eslintrc.yml +++ b/web/.eslintrc.yml @@ -26,6 +26,6 @@ rules: semi: - error - always - @typescript-eslint/no-explicit-any: "off" + typescript-eslint/no-explicit-any: "off" react/react-in-jsx-scope: "off" react/no-unescaped-entities: "off" diff --git a/web/package.json b/web/package.json index 30b50db..56ca008 100644 --- a/web/package.json +++ b/web/package.json @@ -11,7 +11,7 @@ "css": "npx tailwindcss -i ./src/style/app.scss -o ./src/style/app.css --watch" }, "dependencies": { - "@akashnetwork/akashjs": "^0.4.7", + "@akashnetwork/akashjs": "^0.4.11", "@cosmjs/launchpad": "^0.27.1", "@cosmjs/proto-signing": "0.25.4", "@craco/craco": "^6.4.4", @@ -92,4 +92,4 @@ ] }, "typings": "./src/react-app-env.d.ts" -} +} \ No newline at end of file diff --git a/web/src/_helpers/async-utils.ts b/web/src/_helpers/async-utils.ts new file mode 100644 index 0000000..632934c --- /dev/null +++ b/web/src/_helpers/async-utils.ts @@ -0,0 +1,66 @@ +type AsyncFunction = (...params: any[]) => Promise; +type AsyncMapFunction = (elem: T, index: number, array: T[]) => Promise; +type ErrorHandler = (e: any) => void; + +function noop(result: T) { + return result; +} + +export async function asyncForEach(arr: Array, callback: AsyncMapFunction) { + return asyncMap(arr, callback).then(noop); +} + +export async function asyncMap(arr: Array, callback: AsyncMapFunction) { + return Promise.all(arr.map(callback)); +} + +/** + * Wrapper for setTimeout that returns a promise. + * + * @param timeout The delay in milliseconds + * @param action The function to call after the delay + * + * @returns Promise that resolves after the delay + */ +export function schedule(timeout: number, action: TFn) { + return new Promise>((resolve, reject) => { + const fire = () => action().then(resolve, reject); + setTimeout(fire, timeout); + }); +} + +/** + * Returns a function that will accept an error, call the notify function + * with that error, and then schedule a retry using the provided function. + * + * @param fn The function to call after the delay + * @param delay The delay between catch the error and retrying + * @param notify A function to pass the captured error too + * + * @returns A function suitable for use as an error handler + */ +function retryHandler(fn: any, delay: number, notify: ErrorHandler) { + const attempt = () => fn(); + + return (e: any) => { + notify(e); + return schedule(delay, attempt); + }; +} + +/** + * Schedule retries for a function that returns a promise. + * + * @param attempt Function that returns a promise + * @param delays Array of delays between retries + * @param notify Function to call with the error (optional) + * + * @returns New that will only fail if all retries fail + */ +export function retry(attempt: any, delays: number[], notify = noop) { + const addRetry = (promise: Promise, delay: number) => ( + promise.catch(retryHandler(attempt, delay, notify)) + ); + + return delays.reduce(addRetry, attempt()); +} diff --git a/web/src/_helpers/sandbox-chain.ts b/web/src/_helpers/sandbox-chain.ts new file mode 100644 index 0000000..d5c4370 --- /dev/null +++ b/web/src/_helpers/sandbox-chain.ts @@ -0,0 +1,41 @@ +export default { + 'rpc': 'https://rpc.sandbox-01.aksh.pw', + 'rest': 'https://api.sandbox-01.aksh.pw', + 'chainId': 'sandbox-01', + 'chainName': 'Akash Sandbox', + 'chainSymbolImageUrl': 'https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/akashnet/chain.png', + 'stakeCurrency': { + 'coinDenom': 'AKT', + 'coinMinimalDenom': 'uakt', + 'coinDecimals': 6, + 'coinGeckoId': 'akash-network' + }, + 'bip44': { + 'coinType': 118 + }, + 'bech32Config': { + 'bech32PrefixAccAddr': 'akash', + 'bech32PrefixAccPub': 'akashpub', + 'bech32PrefixValAddr': 'akashvaloper', + 'bech32PrefixValPub': 'akashvaloperpub', + 'bech32PrefixConsAddr': 'akashvalcons', + 'bech32PrefixConsPub': 'akashvalconspub' + }, + 'currencies': [ + { + 'coinDenom': 'AKT', + 'coinMinimalDenom': 'uakt', + 'coinDecimals': 6, + 'coinGeckoId': 'akash-network' + } + ], + 'feeCurrencies': [ + { + 'coinDenom': 'AKT', + 'coinMinimalDenom': 'uakt', + 'coinDecimals': 6, + 'coinGeckoId': 'akash-network' + } + ], + 'features': [] +}; \ No newline at end of file diff --git a/web/src/_helpers/chain.ts b/web/src/_helpers/testnet-chain.ts similarity index 100% rename from web/src/_helpers/chain.ts rename to web/src/_helpers/testnet-chain.ts diff --git a/web/src/api/rpc/beta3/deployments.tsx b/web/src/api/rpc/beta3/deployments.tsx index 1aea238..8237e48 100644 --- a/web/src/api/rpc/beta3/deployments.tsx +++ b/web/src/api/rpc/beta3/deployments.tsx @@ -315,6 +315,8 @@ export async function createDeployment( }), }; + console.log(msg); + const tx = await client.signAndBroadcast(account.address, [msg], 'auto', 'Creating the deployment'); return { diff --git a/web/src/components/Deployment/DeploymentActionButton.tsx b/web/src/components/Deployment/DeploymentActionButton.tsx index 6c9c3b8..f3f4de3 100644 --- a/web/src/components/Deployment/DeploymentActionButton.tsx +++ b/web/src/components/Deployment/DeploymentActionButton.tsx @@ -5,6 +5,7 @@ type DeploymentActionButtonProps = { tooltipTitle: string; tooltip: React.ReactNode; linkTo: string; + condition: boolean; children: React.ReactNode; } & ButtonProps; @@ -21,6 +22,7 @@ const DeploymentActionButton: React.FC = (props) => tooltip, linkTo, children, + condition, ...rest } = props; @@ -29,6 +31,7 @@ const DeploymentActionButton: React.FC = (props) => title={tooltipTitle} to={linkTo} className="grow" + condition={condition} >